感谢您帮助淘汰了一个菜鸟。我在两个模型中有以下关系:
class Reader < ActiveRecord::Base
has_many :books, :dependent => :destroy
has_one :last_book, :class_name => "Book"
end
class Book < ActiveRecord::Base
belongs_to :reader
end
我希望last_book成为与读者有关的最新书。
现在,在我的图书控制器中,我正在使用更新
中的类似代码创建如下书籍def create
@reader = Reader.find(params[:reader_id])
@book = @reader.books.new (params[:book])
@reader.last_data = @book
end
我认为这最终会两次写入数据库。有更干净/更有效的方法吗?
答案 0 :(得分:3)
我认为你的协会真的不会像你想要的那样工作。您设置关联的方式,Reader
模型将无法确定哪个图书是last_book
,因为与特定阅读器关联的所有图书都具有相同的reader_id。使用reader.last_book = book
将书籍分配给读者实际上只是将该书籍模型上的reader_id列设置为读者的ID。当你向reader.books
添加一本书时也会发生同样的事情,所以这里确实没有任何区别因素来确定你在致电last_book
时所指的那本书。 / p>
您可能最好只为您尝试建模的last_book
关联定义方法。如果我理解您要正确执行的操作,last_book
应该是最近为读者创建的书籍。在您的Reader模型中执行以下操作:
def last_book
books.order('created_at desc').first
end
并删除此行
has_one :last_book, :class_name => "Book"
这应该允许您执行类似reader.last_book
的操作,它将获取图书协会中最近创建的图书。这样,您就没有任何理由需要明确指定last_book
,只需将图书添加到reader.books
,当您需要上一本书时,只需致电reader.last_book
。
答案 1 :(得分:1)
has_one
允许:order
子句,因此您可以执行此操作:
class Reader < ActiveRecord::Base
has_many :books, :dependent => :destroy
has_one :last_book, :class_name => "Book", :order => "books.created_at desc"
end
然后在您的控制器操作中,您将删除其中一个作业
def create
@reader = Reader.find(params[:reader_id])
@book = @reader.books.new (params[:book])
end
杰夫史密斯的答案也是正确的。