ruby on rails - Retrieve default belongs_to record from a built has_many association in a before_create hook? -


i have 2 models, user , stash.

a user has many stashes, , default_stash. stash has 1 owner (user).

before user created want build stash , assign stash self.default_stash. per instructions here rails - best-practice: how create dependent has_one relations created stash relation, cannot 'create' belongs_to relation @ same time.

user.rb

has_many :stashes, foreign_key: :owner_id belongs_to :default_stash, class_name: 'stash', foreign_key: :owner_id  before_create :build_default_stash def build_default_stash   self.default_stash = stashes.build   true end 

stash.rb

belongs_to :owner, class_name: 'user' 

at point stash can found in user.stashes user.default_stash remains nil, stashes.build not return id in before_create block.

what need can achieved adding following user.rb

after_create :force_assign_default_stash def force_assign_default_stash   update_attribute(:default_stash, stashes.first) end 

but i'd prefer keep within before_create block if possible, validations etc.

i agree describe should work, if you're building associated records in memory , expecting them save -- hooked -- activerecord particularly finicky how define them.

but can make work without changing thing in before_create.

the usual problem need give ar hints relationships inverses of each other. has_many , belongs_to methods take :inverse_of option. problem in case have 1 side of relationship (stash#owner) inverse of 2 on other (user#stashes , user#default_stash), set inverse_of stash#owner?

the solution add has_one stash (call owner_as_default), balance things out. can add inverse_of of definitions, each identifying inverse on other side. end result this:

class user < activerecord::base   has_many   :stashes,       foreign_key: :owner_id, inverse_of: :owner   belongs_to :default_stash, class_name: "stash",    inverse_of: :owner_as_default    ... end  class stash < activerecord::base   belongs_to :owner,            class_name: "user", inverse_of: :stashes   has_one    :owner_as_default, class_name: "user",     foreign_key: :default_stash_id, inverse_of: :default_stash end 

(also, don't need foreign key on belongs_to.)

from there, before_create should work you've written it.

yes, seems lot of redundant defining. can't activerecord figure out foreign keys , whatnot? feel i'm breaking walls making 1 side aware of it's inverse of. maybe in future version of rails ironed out.


Comments

Popular posts from this blog

django - How can I change user group without delete record -

java - Need to add SOAP security token -

java - EclipseLink JPA Object is not a known entity type -