Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Nested forms reject_if is behaving stupidly

#2111

This used to work:

accepts_nested_attributes_for :phone_numbers, :allow_destroy => true, :reject_if => proc { |attr| attr[:number].blank? }

Now it doesn't because the attribute needs to be a string and not a symbol

accepts_nested_attributes_for :phone_numbers, :allow_destroy => true, :reject_if => proc { |attr| attr["number"].blank? }

This should work both ways.

It would also be nice to support a method on the reject_if call

accepts_nested_attributes_for :phone_numbers, :allow_destroy => true, :reject_if => :blank?

Which would call the phone_number.blank? method

This was the way it worked with the attribute_fu plugin which was the best nested forms implementation in Rails before this came along

Reported by ronin-18882 (at lighthouseapp) · March 2nd, 2009 @ 09:03 AM

State: invalid
Milestone: 2.x
Assigned to: Eloy Duran Eloy Duran
Importance: none

Activity

  1. Eloy Duran
    Eloy Duran
    • Assigned user set to Eloy Duran
    • State changed from new to invalid

    accepts_nested_attributes_for :phone_numbers, :allow_destroy => true, :reject_if => proc { |attr| attr[:number].blank? }

    Now it doesn't because the attribute needs to be a string and not a symbol

    accepts_nested_attributes_for :phone_numbers, :allow_destroy => true, :reject_if => proc { |attr| attr["number"].blank? }

    Are you giving it a hash yourself? For instance, from a test case?

    If that's the case, you need to choose one form or the other, not both. In a regular request flow you will always get a HashWithIndifferentAccess. So it won't matter.

    This should work both ways.

    I disagree. This same “issue” comes up in other parts of Rails as well, but most of the times it's in test cases. You as the developer should use the appropriate form.

    It would also be nice to support a method on the reject_if call accepts_nested_attributes_for :phone_numbers, :allow_destroy => true, :reject_if => :blank? Which would call the phone_number.blank? method This was the way it worked with the attribute_fu plugin which was the best nested forms implementation in Rails before this came along

    I would happy to apply such a patch.

    But please open a new ticket for it. As the issue you have, which is mentioned in the title, is a totally different one.

    March 2nd, 2009 @ 11:14 AM

  2. david.cizek (at gmail)
    david.cizek (at gmail)

    The first issue: attr[:number].blank? or attr["number"].blank? cause problems for me, too. Not using testcase, just regular behaviour. From debugging (attrs are the ones pushed to Proc):

    (rdb:1) attrs
    {"value"=>""}
    (rdb:1) attrs[:value]
    nil
    (rdb:1) attrs[:value].blank?
    true
    

    Little more testing:

    (rdb:1) attrs
    {"value"=>"text"}
    (rdb:1) attrs.class
    Hash
    (rdb:1) a=HashWithIndifferentAccess.new
    {}
    (rdb:1) a.class
    HashWithIndifferentAccess
    

    May 21st, 2009 @ 03:16 PM

  3. Eloy Duran
    Eloy Duran

    Hi David,

    I'm not quite sure what it is that you're saying. Could you please elaborate your point? Thanks.

    For what it's worth, this is what I get from your examples which work for me as expected:

    % irb -rrubygems -ractivesupport
    irb(main):001:0> h = HashWithIndifferentAccess.new
    => {}
    irb(main):002:0> h["value"] = ""
    => ""
    irb(main):003:0> h
    => {"value"=>""}
    irb(main):004:0> h["value"].blank?
    => true
    irb(main):005:0> h[:value].blank?
    => true
    irb(main):006:0> h["value"] = "text"
    => "text"
    irb(main):007:0> h["value"].blank?
    => false
    irb(main):008:0> h[:value].blank?
    => false
    

    May 21st, 2009 @ 04:58 PM

  4. david.cizek (at gmail)
    david.cizek (at gmail)

    Hi Eloy,
    sorry for my poor articulation.

    The problem seems to be that in the example

    accepts_nested_attributes_for :phone_numbers, :allow_destroy => true, :reject_if => proc { |attr| attr[:number].blank? }

    the attr seems NOT to be a HashWithIndifferentAccess but just Hash and therefore the Proc condition always fail as written (even if there is nested non blank attr["number"]), needs to be

    ...:reject_if => proc { |attr| attr["number"].blank? }

    and then it works.
    David

    May 28th, 2009 @ 10:39 AM