Ruby on rails 更新_列更新我的instance.xxxable,但不更新实例本身?
我不确定这是因为我使用的是Rails 4,但我很困惑Ruby on rails 更新_列更新我的instance.xxxable,但不更新实例本身?,ruby-on-rails,Ruby On Rails,我不确定这是因为我使用的是Rails 4,但我很困惑 I have the 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_tota
I have the 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
然后使用以下内容修改post
中的average\u stars
列:
star.starable.update(:average_stars, 4)
目前一切正常:
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>
average\u stars
根本没有更新
为什么更新列更新star.starable而不是post?这没有错。您的
star
和post
对象现在就在内存中。您更改了post
的数据库数据,但内存中的post
对象不会自动重新连接到数据库以更新其内部数据。您必须手动执行post.reload
根据代码的上下文,这可能非常好
此外,除非您真的、真的、真的试图提高性能,否则平均值不应该是一个属性/列,而是一个派生属性,您可以在需要时动态计算它
编辑关于生成派生属性,我的意思是您将为其生成一个方法。目前它是数据库中的一列,因此您可以执行以下操作:
Post.first.average_stars # => 4
相反,在您的Post
模型中创建一个名为average\u stars
的方法:
class Post < ActiveRecord::Base
# ...
def average_stars
# calculate
return the_result
end
end
class Post
然后你可以像以前一样调用这个方法,但是不是从数据库中获取它,而是计算它。你可以这样做,这样在你的对象的生命周期内,它就不必重新计算它(除非你强迫它),但要小心。你的帖子和星星创建方法正确吗?根据你的描述,明星和帖子根本没有链接。谢谢你的建议。如何创建派生属性?你能给我举个例子吗?非常感谢!我以为你在说望远镜。
Post.first.average_stars # => 4
class Post < ActiveRecord::Base
# ...
def average_stars
# calculate
return the_result
end
end