Reputation: 193
I have the models:
class Idea < ActiveRecord::Base
has_many :connections, :class_name => 'IdeaConnection', :foreign_key => 'idea_a_id', :dependent => :destroy
has_many :ideas, :through => :connections, :source => :idea_b, :dependent => :destroy
end
class IdeaConnection < ActiveRecord::Base
belongs_to :idea
belongs_to :idea_a, :class_name => 'Idea'
belongs_to :idea_b, :class_name => 'Idea'
belongs_to :relationship
end
class Relationship < ActiveRecord::Base
has_many :idea_connections
end
Idea, as you can see, own itself through Connections (join table). Each Connection entry belongs to Relationship. What I'm trying to do is to, after adding an Idea to another with:
Idea.find(1).ideas << Idea.find(2)
which is working and saving properly, get its connection on join table and update its relationship:
Ex:
Idea.find(1).connections.find_by_idea_b_id(Idea.f
ind(2).id).relationship = Relationship.find(1)
It processes correctly but it won't save.
Please, help, what am I missing?
ps: I don't want to do it by manually editting the relationship_id since it's ugly. ps2: Before you answer, remember the fact that autosave:true do not work for belongs_to/has_many relationships.
Upvotes: 0
Views: 620
Reputation: 1204
You're working with connection object. Remember it.
Your problem is that you call find_by...
method in has_many
association. It returns one record BUT Idea model has no ruby attribute link to that. See here why. That's why Idea#save
cannot call IdeaConnection#save
(remember that for cascade saving connections
realtion must have autosave: true if connection already exists).
So I suggest you two options:
:inverse_of
on Idea#connections
and IdeaConnection#idea_a
relations and preload all records before mangling with Idea.find(1).connections.find_by_idea_b_id(Idea.f
ind(2).id).relationship = Relationship.find(1)
. But I don't recommend you to do so because:As I said you're working with connection object. Just do so:
Idea.find(1).connections.create do |connection|
connection.idea_b = Idea.find(2)
connection.relationship = Relationship.first
end
Upvotes: 1
Reputation: 31
Assignments on the relational object level don't/won't automatically save; you have to tell them to. In ActiveRecord the push method (<<) has save built into it, which is why that was working for you. Setting a value (=) however does not have save built in, so you have to do it manually.
If you're interested, here's a link to another SO question where an answer talks about why push saves: Rails push into array saves object
Upvotes: 0
Reputation: 3597
This line of code won't save it
Idea.find(1).connections.first.relationship = Relationship.first
What you need to do is:
Method #1: ( add the connection to the has_many relation )
Relationship.first.idea_connections << Idea.find(1).connections.first
OR
Method #2: ( add relationship_id to the connection then manually save it)
connection = Idea.find(1).connections.first
connection.relationship_id = Relationship.first.id
connection.save
Upvotes: 0