I have a small testing RailsApp with a simple model, which has a float
attribute called price:
In the model I have overridden the price() method:
class Product < ActiveRecord::Base
def price
return "bla"
end
end
In the console, it behaves as expected:
p = Product.new
p.price = 12.12
p.price
>> "bla"
However, Using the form helper methods, it appears they are not using
the instance methods:
for instance:
<%= form.text_field :price %>
displays: 12.12 in my view, and ignores the overridden AR instance
method.
Why do the form_helpers work this way?
Is this a bug? Or is this approach chosen on purpose?
Regards,
Harm de Laat
Kabisa ICT
However, Using the form helper methods, it appears they are not using
the instance methods:
Kev
--
Kevin Clark
http://glu.ttono.us
At least to me, it 'feel's' like kinda odd behavior.
It seems inconsistent:
validates_numericality_of
if you have an integer field, and the user types in "a12345" instead
of "12345". When displaying error messages you want to display the
value before it was typecast, otherwise it'd just be set to 0. So the
field helper doesn't look directly in the database, it uses
price_before_type_cast, if it exists.
So the behaviour is intentional, if somewhat opaque. Perhaps what's
needed is a way to make it easier to wrap attributes with custom
accessors and mutators?
--
Cheers
Koz
Maybe we could fix validates_numericality_of? Rather than changing
every field helper because of one case? I suppose it is more difficult
that way around however.
The docs really do make it seem like it calls the method. So we'd need
to remember to change those :)
--
Nik Wakelin
(027) 424 5433
munky...@gmail.com
It's also totally random behaviour to sometimes get a String from an
otherwise numeric attribute. I'm not sure that there's a really
simple fix that'll magically solve every case we could come across,
but I do believe that if we find the cases where this behaviour is
biting people, we'll probably be able to solve those cases nicely.
My understanding is that the most common case is something along the
lines of "I want to store the number of cents instead of a dollar
amount"? What else breaks?
It seems the real problem is two fold:
1) it's kinda surprising that overriding the accessors doesn't
automatically work
2) The docs outright lie and tell you that it will work.
> The docs really do make it seem like it calls the method. So we'd need
> to remember to change those :)
Indeed.
--
Cheers
Koz
1) If an overridden accessor is there, (i.e you've defined
Product#price) then that gets called
2) Otherwise, we call price_before_type_cast
(i.e the opposite of the current logic :))
And we amend the documents.
On 5/22/07, Michael Koziarski <mic...@koziarski.com> wrote:
>
1) If an overridden accessor is there, (i.e you've defined
Product#price) then that gets called
2) Otherwise, we call price_before_type_cast
The real problem seems to be that people want to format attributes
before they display them (credit card, phone number). So, how about we
allow that. Could be as simple as:
<%= text_field :person, :name, :formatter => :random -%>
class Person < ActiveRecord::Base
def random(value)
value.upcase * 4
end
end
Thoughts?
--josh
--
Josh Susser
http://blog.hasmanythrough.com
+1
I would love for this to be in core. I have been feeling the pain of
hacking around this for sometime.
Nik, will you do the patch or should I?
Koz, do you think this would be applied?
--
Thank you,
Steven A Bristol
st...@lesseverything.com
Sometimes (or perhaps generally) form builders and objects are too
closely tied -- surely you do not want to pollute your model with a
lot of user interface stuff. Instead, a level of indirection is
useful, such as a form model:
class ProductForm
def initialize(object)
@object = object
end
def dutch_price
('%.2f' % @object.price).gsub('.', ',')
end
def dutch_price=(price)
@object.price = price.to_s.gsub(',', '.')
end
def method_missing(name, *args, &block)
@object.send(name, *args, &block)
end
end
Now you can do:
<% form_for :product, @product do |form| %>
<%= form.text_field :title %>
<%= form.text_field :dutch_price %>
<% end %>
where @product could be initialized thus:
@product = ProductForm.new(Product.find(params[:id]))
Alexander.
Another thing to check is if it's feasible to make the form helpers
only use _before_type_cast if the field is invalid? Perhaps that'll
allow for a relatively low-impact solution?
--
Cheers
Koz
This would mean that if there is a validation error in some other
field, the typecast value gets displayed back to the user. We are
using Chronic for date parsing - I don't want the shiny natural
language date that the user entered to disappear halfway through the
validation process.
Maybe only use before_type_cast if there are _any_ validation errors
for the current submission?
I don't think there's anything wrong with the current approach, but I
agree that the documentation could be clearer.
--max
>
> --
> Cheers
>
> Koz
>
> >
>
Here's another +1 on being able to format the value in a form helper
before it's displayed. This shouldn't be in my model since it's
purely a display issue. I'd be happy if I could specify another
helper method to perform the formatting. Something like:
<%= text_field :product, :price, :formatter => :number_to_currency -%>
-Derrick Spell
-bd
On May 30, 10:46 pm, "Derrick Spell" <derrick.sp...@gmail.com> wrote:
> On 5/25/07, Steven A Bristol <stevenbris...@gmail.com> wrote:
>
>
>
>
>
> > > On May 24, 2007, at 10:22 PM, Nik Wakelin wrote:
>
> > > > How about this for a solution.
>
> > > > The real problem seems to be that people want to format attributes
> > > > before they display them (credit card, phone number). So,
> > how about we
> > > > allow that. Could be as simple as:
>
> > > > <%= text_field :person, :name, :formatter => :random -%>
>
> > +1
>
> > I would love for this to be in core. I have been feeling the pain of
> > hacking around this for sometime.
>
> > Nik, will you do the patch or should I?
>
> > Koz, do you think this would be applied?
>
> > --
> > Thank you,
> > Steven A Bristol