Question

je crois que datetime_select est la magie noire. Ce que j'essaie vraiment de comprendre, c'est le tout 1i,2i,3i,4i... plusieurs paramètres. Plus précisément, comment est-il géré à l'arrière (activeRecord, autre chose?). Qu'y a-t-il avec le «je» après le nombre de commandes? Est-ce un spécificateur de type? Si oui, quels sont les autres types disponibles? J'ai lu la source de date_helper.rb et c'est assez opaque.

Voici ma motivation:

j'ai un :datetime colonne de mon modèle et je veux saisir dans la vue via deux text_fieldS: un pour la date et un pour le temps. Ils doivent être validés, fusionnés ensemble, puis stockés dans la colonne DateTime. En fin de compte, j'utiliserai un calendrier JavaScript pour saisir les dates du champ Date.

Alors, quelqu'un a-t-il fait cela? J'ai essayé d'utiliser des attributs virtuels (incroyablement sans papiers en plus du railscast rudimentaire) et le problème était que lorsqu'un nouvel objet ActiveRecord est créé et a des attributs nuls, l'attribut virtuel échoue (méthode non définie strftime pour Nil Class, ce qui a du sens).

Quelqu'un a-t-il des suggestions ou des meilleures pratiques? Merci!

Était-ce utile?

La solution

J'avais la même question. Voici ce que j'ai trouvé ...

http://apidock.com/rails/activerrecord/base/assign_multiparameter_attributes

attribution_multiparameter_attributes (paires) privé

Instancie des objets pour toutes les classes d'attribut qui ont besoin de plus d'un paramètre de constructeur. Cela se fait en appelant nouveau sur le type de colonne ou le type d'agrégation (via Composé_OF) avec ces paramètres. Ainsi, ayant les paires écrits_on (1) = "2004", écrit_on (2) = "6", écrit_on (3) = "24", instanciera écrit_on (un type de date) avec date.new ("2004", "6 "," 24 "). Vous pouvez également spécifier un caractère typast dans les parenthèses pour avoir les paramètres typiqueés avant d'être utilisés dans le constructeur. Utilisez i pour fixnum, f pour float, s pour la chaîne et A pour le tableau. Si toutes les valeurs d'un attribut donné sont vides, l'attribut sera défini sur nil.

Les nombres sont donc pour les paramètres du type de données que la colonne est. Le "I" doit le convertir en un entier. D'autres types sont pris en charge comme "F" pour le flotteur, etc.

Vous pouvez voir ici execure_callstack_for_multiparameter_attributes qu'il détecte le type de cible et l'instancie en passant les valeurs.

Donc, pour essayer de répondre directement à la question posée, je ne pense pas que vous puissiez l'utiliser pour remplacer la façon dont une datetime est créée car elle utilise le constructeur qui ne prend pas en charge le format que vous souhaitez transmettre. Ma réalisation était de Divisez la colonne DateTime sur une seule date et une colonne unique. Ensuite, l'interface utilisateur pourrait fonctionner comme je le voulais.

Je me demande s'il pourrait être possible de créer des accessoires d'attribut sur la classe qui représentent la date et l'heure séparément, mais gardez une seule colonne DateTime. Ensuite, le formulaire pourrait faire référence à ces accessoires séparés. Cela pourrait être réalisable. Une autre option pourrait être à utiliser composé de Pour personnaliser davantage le type.

J'espère que cela aide quelqu'un d'autre. :)

Autres conseils

Voici ce que j'ai fini par trouver. Si quelqu'un a des commentaires, faites-le moi savoir. J'adorerais obtenir des commentaires.

  validate :datetime_format_and_existence_is_valid  
  before_save :merge_and_set_datetime   

  # virtual attributes for date and time allow strings
  # representing date and time respectively to be sent
  # back to the model where they are merged and parsed
  # into a datetime object in activerecord
  def date
    if (self.datetime) then self.datetime.strftime "%Y-%m-%d"
    else @date ||= (Time.now + 2.days).strftime "%Y-%m-%d" #default
    end
  end
  def date=(date_string)
    @date = date_string.strip
  end
  def time
    if(self.datetime) then self.datetime.strftime "%l:%M %p"
    else @time ||= "7:00 PM" #default
    end
  end
  def time=(time_string)
    @time = time_string.strip
  end

  # if parsing of the merged date and time strings is
  # unsuccessful, add an error to the queue and fail
  # validation with a message
  def datetime_format_and_existence_is_valid    
    errors.add(:date, 'must be in YYYY-MM-DD format') unless
      (@date =~ /\d{4}-\d\d-\d\d/) # check the date's format
    errors.add(:time, 'must be in HH:MM format') unless # check the time's format
      (@time =~ /^((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AaPp][Mm]))$|^(([01]\d|2[0-3])(:[0-5]\d){0,2})$/)
    # build the complete date + time string and parse
    @datetime_str = @date + " " + @time
    errors.add(:datetime, "doesn't exist") if 
      ((DateTime.parse(@datetime_str) rescue ArgumentError) == ArgumentError)
  end

  # callback method takes constituent strings for date and 
  # time, joins them and parses them into a datetime, then
  # writes this datetime to the object
  private
  def merge_and_set_datetime
    self.datetime = DateTime.parse(@datetime_str) if errors.empty?
  end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top