从 ActiveRecord::Relaiton 获取 has_many
Get has_many from ActiveRecord::Relaiton
是否可以从 ActiveRecord::Relation 中获取 has_many 条记录?
即Book.where(fiction: true).pages
相对于 Book.where(fiction: true).collect { |book| book.pages }
理想情况下,我希望能够使用一个 ActiveRecord 查询获取所有记录,这样我就不必在内存中构建数组,并使代码更简洁一些,尤其是当关系有多个级别(即 Book.where(fiction: true).pages.words
好在下面,
Book.where(fiction: true).collect { |book| book.pages }
可以写成:
Page.joins(:book).where("books.fiction = ?", true)
类似的方式:
Word.joins(page: :book).where("books.fiction = ?", true)
您可以使用选项 through
.
在父对象(假设它是 Library
)和 pages
之间创建单独的 has_many
关系
class Page
belongs_to :book
end
class Book
belongs_to :library
has_many :pages
end
class Library
has_many :books
has_many :pages, through: :books
has_many :fiction_books, -> { where(fiction: true) }, class_name: 'Book', foreign_key: 'library_id'
has_many :fiction_pages, through: :fiction_books, source: :pages
end
Library.first.fiction_pages
我会注意到父对象将帮助您构建具有过于复杂逻辑的正确架构,因此您将只写 current_library.fiction_pages
而不是 Book.where(fiction: true).pages
如果应用程序的逻辑不需要这样的父对象,你可以通过单独的助手来伪造它,它可以放在 ApplicationController
:
class ApplicationController
helper_method :current_library
protected
def current_library
@current_library ||= Library.first
end
end
在这种情况下,所有 AR 对象都应通过库方法或通过库的子对象获取。
是否可以从 ActiveRecord::Relation 中获取 has_many 条记录?
即Book.where(fiction: true).pages
相对于 Book.where(fiction: true).collect { |book| book.pages }
理想情况下,我希望能够使用一个 ActiveRecord 查询获取所有记录,这样我就不必在内存中构建数组,并使代码更简洁一些,尤其是当关系有多个级别(即 Book.where(fiction: true).pages.words
好在下面,
Book.where(fiction: true).collect { |book| book.pages }
可以写成:
Page.joins(:book).where("books.fiction = ?", true)
类似的方式:
Word.joins(page: :book).where("books.fiction = ?", true)
您可以使用选项 through
.
Library
)和 pages
之间创建单独的 has_many
关系
class Page
belongs_to :book
end
class Book
belongs_to :library
has_many :pages
end
class Library
has_many :books
has_many :pages, through: :books
has_many :fiction_books, -> { where(fiction: true) }, class_name: 'Book', foreign_key: 'library_id'
has_many :fiction_pages, through: :fiction_books, source: :pages
end
Library.first.fiction_pages
我会注意到父对象将帮助您构建具有过于复杂逻辑的正确架构,因此您将只写 current_library.fiction_pages
Book.where(fiction: true).pages
如果应用程序的逻辑不需要这样的父对象,你可以通过单独的助手来伪造它,它可以放在 ApplicationController
:
class ApplicationController
helper_method :current_library
protected
def current_library
@current_library ||= Library.first
end
end
在这种情况下,所有 AR 对象都应通过库方法或通过库的子对象获取。