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

How do you change vbulletin's home page to the forums instead of the default (CMS or Activity Stream)? -

c++ - Troubles when compiling phash program -