Dans Rails, existe-t-il un moyen de spécifier un TYPE que vous souhaitez qu'un attr_accessor soit et de le valider à l'aide de la validation Rails intégrée ?

StackOverflow https://stackoverflow.com/questions/5463337

Question

Je n'ai jamais réussi à trouver une bonne façon de procéder, alors j'ai pensé demander.

Par exemple, dans un modèle ActiveRecord, les attributs basés sur la base de données sont automatiquement convertis en types appropriés basés sur la base de données.Si j'ai un Category modèle, et il a quelques attributs, disons name et category_id, si je fais comme ça :

Category.new(params[:category])

Rails le sait name est une chaîne et category_id est un entier.

Disons que j'ai plusieurs attributs transitoires/synthétiques que je souhaite valider, et qu'ils ont des types spécifiques.Je souhaite les soumettre à partir d'un formulaire et j'aimerais qu'ils soient automatiquement convertis en chaîne, en entier ou en date (par exemple) en fonction de la façon dont ils sont définis.

Si je devais déclarer quelque chose dans un modèle Rails comme :

attr_accessor :some_number_variable
attr_accessor :some_date

Existe-t-il un moyen intégré de dire à Rails "J'aimerais que vous transformiez le premier en un entier et le second en une date, quand je vais Category.new(params[:category])" tant que params[:category][:some_number_variable] et params[:category][:some_date] font partie des données soumises au contrôleur (je me rends compte que l'exemple Date pourrait être un peu plus délicat étant donné les nombreux formats de date disponibles).

Était-ce utile?

La solution

Aucune des réponses ne répond vraiment à la question.Je crois que la bonne réponse à ces questions est simplement « Non ».Les réponses abordent toutes deux des solutions de contournement potentielles au fait que la réponse à la question est « Non », et les deux sont des commentaires/idées valables.

Autres conseils

Depuis Rails 5, il y a le API d'attribut que vous pouvez utiliser comme ceci :

class SomeModel < ActiveRecord::Base
  attribute :a_checkbox_name, :boolean, default: false
end

Vous pouvez définir des valeurs par défaut et définir vos propres types, entre autres choses intéressantes.Ensuite, vous pouvez valider ces attributs (virtuels ou non) comme n'importe quel autre attribut soutenu par une base de données.

attr_accesor crée simplement des méthodes de lecture/écriture, et cela vient de Rubis, pas Rails.La méthode Rails qui, je crois, est souvent confuse est attr_accessible qui sert un but différent.Si vous souhaitez effectuer un cast lorsque l'attribut est lu, vous pouvez simplement remplacer le lecteur.

attr_accessor :some_number_variable

def some_number_variable
  @some_number_variable.to_i
end

Cela vous donnera au moins l'écrivain gratuitement.C'est la meilleure solution que je connaisse pour ce que (je pense) vous décrivez.

MODIFIER:En ce qui concerne la validation, je pense que si vous utilisez Rails 3, il vous sera beaucoup plus facile d'effectuer une validation sur ce type d'attributs (je ne l'ai pas fait donc je ne peux pas le dire avec certitude).Maintenant que les validations ne sont plus directement liées à ActiveRecord, je le croirais possible.

Je suppose que par attribut « transitoire/synthétique », vous entendez un attribut virtuel ?

Si tel est le cas, il n'existe aucune fonction Rails intégrée qui fasse cela à laquelle je puisse penser, mais une solution serait simplement d'écrire un module pour ces attributs et de l'inclure dans le modèle.Ou s'il devait être dynamique, vous pouvez appeler l'attribut quelque chose comme :some_variable_integer, puis gérer ces attributs dynamiques avec method_missing, lire le nom de la méthode et le convertir dans le type requis.

À mon avis, c'est un peu compliqué, donc les validations dans le modèle sont vraiment votre meilleur pari si ce que vous cherchez à faire peut les prendre en charge.

utiliser avant_créer..

class Category
  attr_accessor :some_number_variable, :some_date
  before_create :validate

 private

   def validate
     return unless !!params[:category]
     #do variable casting here
   end
end

Ajoutez ce qui suit à votre modèle :

columns_hash["birth_date"] = ActiveRecord::ConnectionAdapters::Column.new("birth_date", nil, "date")

référence: Rails ActiveRecord :: MultiparameterAssignmentErrors

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top