ruby on rails - Set activerecord model defaults before mass assignment initialize -
i need defaults (from remote service) in modela
set before object passed view modelacontroller#new
. have used after_initialize
this. however, in #create
have problem. if use model_b.create_model_a(some_attributes)
, attributes passed in during initialization , overwritten after_initialize
call:
class modela < activerecord::base after_initialize :set_defaults, if: :new_record? def set_defaults self.c = "default" #actually remote call, not can set database default end end class modelb < activerecord::base belongs_to :model_a end class modelacontroller < applicationcontroller #modela nested under modelb in routes.rb #get /model_bs/:model_b_id/model_as/new def new model_b = modelb.find(params[:model_b_id]) #no problem respond_with model_b.build_model_a end #post /model_bs/:model_b_id/model_as def create model_b = modelb.find(params[:id]) #problem: respond_with model_b.create_model_a({c: "not default"}) #at point model_a instance still has attribute c set "default" end ... end
i separate create steps:
model_b = modelb.find(params[:id]) model_a = model_b.build_model_a #should fire after_initialize model_a.update_attributes({c: "not default"}) #overwrite default c value
but feel makes lifecycle of modela bit of trap other programmers. looks obvious candidate refactoring last 2 lines one, create problem again. there neater solution?
make conditional assignment:
def set_defaults self.c ||= "default" end
alternatively instead of after_initialize hook set default in attribute reader. way set default when need attribute value, saves remote call if don't need it:
def c super || self.c = 'default' end
Comments
Post a Comment