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
Post a Comment