ActiveRecord relationship ID change

Hi guys,
I’m having a problem with a belongs_to relationship.
The thing is:
class Banner < ActiveRecord::Base
belongs_to :campaign

end

class Campaign < ActiveRecord::Base
has_one :banner, :dependent => :destroy
accepts_nested_attributes_for :banner

end

If I do:
campaign.update_attribute(:banner_attributes, {:content => “Changed”})
campaign.banner.id is incremented by one, asi if a new instance is
being created.

Also, if I do:
campaign.update_attributes({:banner_attributes, {:content =>
“Changed”}})

campaign.banner.id is nil.

Any ideas?

This is my rspec.

it “should not change banner id when banner updated” do
Advertiser = mock
advertiser = mock

Advertiser.stub!(:find).and_return(advertiser)
advertiser.stub!(:id).and_return(1)
advertiser.stub!(:new_record?).and_return(false)
advertiser.stub!(:destroyed?).and_return(false)

banner = Banner.create(:content => "Some content", :deep_link =>

http://test.com”)
banner.should be_valid

campaign = Campaign.create(:advertiser_id => advertiser.id,

:banner_id => banner.id, :website_code => “test”)
campaign.banner = banner

campaign.banner.id.should == banner.id

campaign.update_attribute(:banner_attributes, {:content => 

“Changed”})

campaign.banner.content.should == "Changed"
campaign.banner.id.should == banner.id

end

This is the output for the update_attribute case:
[leonardo@anarchie app_core]$ rspec spec/campaign_spec.rb -d
…F

Failures:

  1. Campaign should not change banner id when banner updated
    Failure/Error: campaign.banner.id.should == banner.id
    expected: 36,
    got: 37 (using ==)

    ./spec/campaign_spec.rb:93

Finished in 0.23597 seconds
7 examples, 1 failure

And this is the output for the update_attributes case:
[leonardo@anarchie app_core]$ rspec spec/campaign_spec.rb -d
…F

Failures:

  1. Campaign should not change banner id when banner updated
    Failure/Error: campaign.banner.id.should == banner.id
    expected: 38,
    got: nil (using ==)

    ./spec/campaign_spec.rb:93

Finished in 0.20556 seconds
7 examples, 1 failure

Any thoughts?

Thanks a lot in advance!


Leonardo M…
There’s no place like ~

I’m pretty sure you need to pass the ID along with the attributes,
otherwise
Rails creates a new instance:

campaign.update_attribute(:banner_attributes, {:id => banner.id,
:content =>
“Changed”})

instead of

campaign.update_attribute(:banner_attributes, {:content => “Changed”})

The other option would be to just update the banner directly:

campaign.banner.content = “Changed”

On Tue, Dec 21, 2010 at 4:44 PM, Tim S. [email protected] wrote:

I’m pretty sure you need to pass the ID along with the attributes, otherwise
Rails creates a new instance:
Yes, that’s pretty much what’s happening.
I, actually, was a moron, since I should have see the code in first
place.
The update_attributes method in ActiveRecord::Base is stupidly simple
and it’s really clear what it does:

2666 def update_attributes(attributes)
2667
with_transaction_returning_status(:update_attributes_inside_transaction,
attributes)
2668 end
2669
2670 def update_attributes_inside_transaction(attributes)
#:nodoc:
2671 self.attributes = attributes
2672 save
2673 end

Duh! Sorry guys. My bad.
Thanks anyway for your time, Tim.


Leonardo M…
There’s no place like ~