ruby on rails - update_column updates my instance.xxxable but not the instance itself? -


i'm not sure because i'm using rails 4 i'm puzzled.

i have following models set:  class post < activerecord::base   has_many :stars, :as => :starable, :dependent => :destroy    belongs_to :user end  class star < activerecord::base   before_create :add_to_total_stars    belongs_to :starable, :polymorphic => true    protected    def add_to_total_stars     if [post].include?(starable.class)       self.starable.update_column(:total_stars, starable.total_stars + self.number)     end   end end  class user < activerecord::base   has_many :posts, dependent: :destroy   has_many :votes, dependent: :destroy end 

so created star , post in rails console:

star = post.stars.build number: 2 post = post.create title: "test", content: "test", user_id: 1 

then used following modify average_stars column in post:

star.starable.update(:average_stars, 4) 

everything ok far:

star.starable  => #<post id: 9, title: "test", content: "test", created_at: "2013-07-25 16:05:52", updated_at: "2013-07-25 16:05:52", user_id: 1, average_stars: 4, total_stars: 0.0>  

but wanted check post , saw this:

 post  => #<post id: 9, title: "test", content: "test", created_at: "2013-07-25 16:05:52", updated_at: "2013-07-25 16:05:52", user_id: 1, average_stars: 0, total_stars: 0.0>  

average_stars wasn't updated @ all.

why update_column updating star.starable not post?

this not wrong. star , post objects in memory. changed db data post, yourpost object in memory doesn't automatically reconnect database update internal data. you'd have post.reload that, manually.

depending on context of code, may fine.

also, unless you're really, really, trying improve upon performance, average_stars shouldn't attribute/column, rather derived attribute can calculate dynamically when need it.

edit regarding making derived attribute, mean make method it. it's column in database, can things like:

post.first.average_stars # => 4 

instead, make method named average_stars in post model:

class post < activerecord::base   # ...   def average_stars      # calculate      return the_result   end end 

and can call method in same way before, instead of grabbing database, it's being calculated. can memoize life time of object won't have recalculate (unless force to) careful that.


Comments

Popular posts from this blog

php - get table cell data from and place a copy in another table -

javascript - Mootools wait with Fx.Morph start -

php - Navigate throught databse rows -