8
votes

Rails Rails: valeur de formatage avant de la définir dans le modèle?

J'ai des champs de formulaires où l'utilisateur entre dans:

  • percents: 50,5% code> li>
  • argent: 144,99 $ code> li>
  • Dates: Mercredi 12 janvier 2010 Code> Li> ul>

    ... p>

    Le % et ARGTER code> Les attributs de type sont enregistrés comme décimal code> champs avec Actioniverecord et les dates sont DateTime CODE> ou DATE CODE> Champs. P>

    Il est facile de convertir entre les formats en JavaScript, et vous pouvez les convertir théoriquement vers l'Actionecord. Format acceptable OnSubmit code>, mais ce n'est pas une solution décente. p>

    Je voudrais faire quelque chose de remplacer les accesseurs de ActiveRecord, donc lorsqu'ils sont définis, il les convertit de n'importe quelle chaîne vers format, mais ce n'est pas le meilleur non plus. p>

    Ce que je ne veux pas, c'est avoir à les exécuter à travers un objet de processeur distinct, qui nécessiterait quelque chose comme celui-ci dans un contrôleur: P>

    class Product < ActiveRecord::Base
      format :price, :except => /\$/
    end
    
    product = Product.new(:price => "$199.99")
    product.price #=> #<BigDecimal:10b001ef8,'0.19999E3',18(18)>
    


1 commentaires

Il y a un gemnié nommé 'attribut_normalizer' qui fonctionne-t-il


3 Réponses :


13
votes

Vous pouvez utiliser un crochet avant validation pour normaliser vos paramètres tels que avant_validation xxx


3 commentaires

Si vous modifiez cette valeur dans votre application, vous devez effectuer ce processus bidirectionnel bidirectionnel, quel que soit le processus que vous effectuez dans l'avant_validation dont vous avez besoin pour inverser en remplaçant le getter, voir la réponse de IAIN à cette question pour un exemple.


En supposant que le prix est un nombre dans la base de données, comme écrit ci-dessus, cela se produira après la coulée de type. Signification Entrée utilisateur de "1AB23CD45" obtiendrait un traitement à 1 avant de voir le format_params. Après une longue journée, je sais maintenant que devrait être auto.Price = prix_be_type_cast.gsub ([[[^ 0-9 \.] /, '') L'utilisation de l'accessor automatiquement généré * _bore_type_cast est un secret crucial.


Autres addendes: Vous avez réellement besoin de prix_before_type_cast.to_s.gsub (...) car sinon vous appuyez sur «Méthode inconnu GSub pour les erreurs de type Fixnum», par exemple lorsqu'une usine attribue un numéro à prix.



33
votes

Vous pouvez remplacer le setter ou le getter.

remplacer le setter: p> xxx pré>

remplacer le getter: p>

class Product < ActiveRecord::Base
  def price
    self[:price].to_s.gsub(/[^0-9\.]/, ''))
  end
end


0 commentaires

1
votes

Utilisez monétize gem pour analyse des numéros d'analyse.

Exemple P>

Monetize.parse(val).amount


0 commentaires