Hi,
I am trying to use the WhitespaceKiller as referenced here:
http://wiki.rubyonrails.com/rails/show/HowToStripWhitespaceFromModelFields
However, it does not work for attr_accessors such as:
attr_accessor :password
Here is an inspect snippet of my User object:
<User:0x3865798 @password_confirmation="", @password="",
@attributes={"name"=>"Tom Davies",
"address1"=>"123 No Way", ...}>
The WhitespaceKiller only loops through the attributes (which the
attr_accessors are not part of) using this code:
def before_validation(record)
record.attributes.each do | attr, val|
if !val.nil? && val.respond_to?(:strip)
s = val.strip
s.size == 0? record[attr] = nil : record[attr] = s
end
end
end
Is there a concise way to modify that method to include the attr_accessors?
Thanks,
Tom
Tom Davies wrote:> The WhitespaceKiller only loops through the attributes (which the > attr_accessors are not part of) using this code: > > Is there a concise way to modify that method to include the attr_accessors?Something like: def before_validation(record) for var in record.instance_variables.collect {|v| v[1..-1]} - [''attributes'',''new_record''] + record.attribute_names setter_meth = var + ''='' if record.respond_to?(var) && record.respond_to?(setter_meth) val = record.send(var) if !val.nil? && val.respond_to?(:strip) s = val.strip record.send(setter_meth, s.size == 0 ? nil : s) end end end end -- We develop, watch us RoR, in numbers too big to ignore.
Thanks! That seems to do the trick. I just have one question.
If I try to test it by replacing the record with an instance of my
model User class, it does not pick up the attr_accessors. For
example:
<% @user = User.new
for var in @user.instance_variables.collect {|v| v[1..-1]} -
[''attributes'',''new_record''] +
@user.attribute_names %>
<%= var %>
<% end %>
Is the record passed to the Observer methods something other than a
direct instance of the model class?
Thanks again,
Tom
On 9/14/05, Mark Reginald James
<mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org>
wrote:> Tom Davies wrote:
>
> > The WhitespaceKiller only loops through the attributes (which the
> > attr_accessors are not part of) using this code:
> >
> > Is there a concise way to modify that method to include the
attr_accessors?
>
> Something like:
>
> def before_validation(record)
> for var in record.instance_variables.collect {|v| v[1..-1]} -
[''attributes'',''new_record''] +
record.attribute_names
> setter_meth = var + ''=''
> if record.respond_to?(var) && record.respond_to?(setter_meth)
> val = record.send(var)
> if !val.nil? && val.respond_to?(:strip)
> s = val.strip
> record.send(setter_meth, s.size == 0 ? nil : s)
> end
> end
> end
> end
>
> --
> We develop, watch us RoR, in numbers too big to ignore.
>
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
Tom Davies wrote:> Thanks! That seems to do the trick. I just have one question. > > If I try to test it by replacing the record with an instance of my > model User class, it does not pick up the attr_accessors. For > example: > > <% @user = User.new > for var in @user.instance_variables.collect {|v| v[1..-1]} - > [''attributes'',''new_record''] + @user.attribute_names %> > <%= var %> > <% end %> > > Is the record passed to the Observer methods something other than a > direct instance of the model class?It''ll only pick up attr_accessors that have been set to some value in the instance. Also, if you want to get a separate list of the accessors, and also to increase efficiency, you could move the respond_to?s out of the loop. e.g. inst_vars = record.instance_variables.collect {|v| v[1..-1]} - [''attributes'',''new_record''] accessors = ivars.delete_if { |iv| !(record.respond_to?(iv) && record.respond_to?(iv+''='')) } for var in accessors + record.attribute_names val = record.send(var) if !val.nil? && val.respond_to?(:strip) s = val.strip record.send(var+''='', s.size == 0 ? nil : s) end end -- We develop, watch us RoR, in numbers too big to ignore.
Thanks Mark. I added your first reply to the WhitespaceKiller wiki page. I am not too concerned with efficiency here... as the number of accessors and attributes is very small for all of my models... but I appreciate your help. Tom On 9/15/05, Mark Reginald James <mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:> Tom Davies wrote: > > Thanks! That seems to do the trick. I just have one question. > > > > If I try to test it by replacing the record with an instance of my > > model User class, it does not pick up the attr_accessors. For > > example: > > > > <% @user = User.new > > for var in @user.instance_variables.collect {|v| v[1..-1]} - > > [''attributes'',''new_record''] + @user.attribute_names %> > > <%= var %> > > <% end %> > > > > Is the record passed to the Observer methods something other than a > > direct instance of the model class? > > It''ll only pick up attr_accessors that have been set to some value > in the instance. > > Also, if you want to get a separate list of the accessors, and also to > increase efficiency, you could move the respond_to?s out of the loop. > > e.g. > > inst_vars = record.instance_variables.collect {|v| v[1..-1]} - [''attributes'',''new_record''] > accessors = ivars.delete_if { |iv| !(record.respond_to?(iv) && record.respond_to?(iv+''='')) } > for var in accessors + record.attribute_names > val = record.send(var) > if !val.nil? && val.respond_to?(:strip) > s = val.strip > record.send(var+''='', s.size == 0 ? nil : s) > end > end > > > > -- > We develop, watch us RoR, in numbers too big to ignore. > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >