2011-01-31 16 views
8

Tengo un problema con los formularios y el money gem.Rails money gem and form builder

Este es mi problema:

  1. puedo crear un registro que tiene un campo "cantidad" (mapeado en el objeto dinero). Digamos que ingreso 10 (dólares).
  2. La gema dinero lo convierte a 1000 (centavos)
  3. que editar el mismo registro y el formulario de pre-rellena el campo cantidad que 1000
  4. Si salvo el registro sin cambiar nada, que convertirá el 1000 (dólares) a 100000 (centavos)

¿Cómo hago que muestre la cantidad pre-poblada en dólares en lugar de centavos?

Editar:

traté de editar el _form.html así:

= f.text_field(:amount, :to_money) 

y me sale este error:

undefined method `merge' for :to_money:Symbol 
+0

Es 1345 Creo que el formulario recupera el valor almacenado sin convertirlo a dólares. – David

+0

Entonces, ¿cómo es que 1,000 se está convirtiendo a 100 y no muestra 1,000? Algo está mal allí. En segundo lugar (no he usado la gema de dinero) pero sospecho que el lector de atributos para el campo de importe no está convirtiendo el valor. O tal vez esto debe ser hecho por usted y no la joya? Algún código que publiques ayudará. Además, realice una inspección en el registro cargado y vea cuál es el valor del campo de cantidad. – Zabba

+0

Disculpa que fue un error tipográfico. Se rellena previamente como 1000. – David

Respuesta

11

Dada una migración de la siguiente manera:

class CreateItems < ActiveRecord::Migration 
    def self.up 
    create_table :items do |t| 
     t.integer :cents 
     t.string :currency 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :items 
    end 
end 

Y un modelo como fol mínimos:

class Item < ActiveRecord::Base 
    composed_of :amount, 
    :class_name => "Money", 
    :mapping  => [%w(cents cents), %w(currency currency_as_string)], 
    :constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) }, 
    :converter => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't conver #{value.class} to Money") } 
end 

A continuación, este código de formulario debería funcionar perfectamente (acabo probados bajo Rails 3.0.3), la visualización y el ahorro de la cantidad de dinero cada vez que guarde/editar correctamente. (Esto está usando los métodos de actualización/creación de andamios por defecto).

<%= form_for(@item) do |f| %> 
    <div class="field"> 
    <%= f.label :amount %><br /> 
    <%= f.text_field :amount %> 
    </div> 
    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 
+0

Su ejemplo me hizo detectar el problema. En mi migración tengo la cantidad de tte. Enteros y en mi modelo he compuesto_de: cantidad. Esto causó un conflicto. Gracias. – David

+3

Gracias por esta respuesta. Justo y digo para otros, donde '[% w (cents cents)' ... está escrito, los primeros 'centavos' representan tu columna en ': items' y los segundos' centavos' son un método de la gema. –

3

Si tiene varios campos de dinero en su tabla y no puede nombrarlos a todos "centavos".

class CreateItems < ActiveRecord::Migration 
    def self.up 
    create_table :items do |t| 
     t.integer :purchase_price_cents 
     t.string :currency 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :items 
    end 
end 

que cambiaría su modelo a

class Item < ActiveRecord::Base 

    composed_of :purchase_price, 
    :class_name => "Money", 
    :mapping  => [%w(purchase_price_cents cents), %w(currency currency_as_string)], 
    :constructor => Proc.new { |purchase_price_cents, currency| Money.new(purchase_price_cents || 0, currency || Money.default_currency) }, 
    :converter => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't convert #{value.class} to Money") } 

end 
+0

Muy buena respuesta. Dar un ejemplo con una columna "purchase_price_cents" es menos ambiguo porque deja en claro cuál es la columna y cuál es la función. (% w (purchase_price_cents centavos) vs.% w (centavos de euro) – Christoph

3

Ahora puede editar campos monetarios directamente (dinero-carriles 1.3.0):

# add migration 
add_column :products, :price, :price_cents 

# set monetize for this field inside the model 
class Product 
    monetize :price_cents 
end 

# inside form use .price instead of .price_cents method 
f.text_field :price 

Ver https://stackoverflow.com/a/30763084/46039