繁体   English   中英

ActiveRecord has_one具有动态范围

[英]ActiveRecord has_one with a dynamic scope

我有这个

class Student
  has_many :assignments
end

class Assignment
  belongs_to :student
  belongs_to :book
end

class Book
  has_many :assignments
end

要找到学生的“哈利·波特”作业,我正在这样做

@student.assignments.find_by_book_id(Book.find_by_name('Harry Potter'))

有没有办法使它成为Student模型的has_one关联?

这样的东西(这里是伪代码)

class Student
  has_many :assignments
  has_one  :harry_potter_assigment, -> { where book_id: Book.find_by_name('Harry Potter') }, class: 'Assignment'
end

如果不使用has_one ,还有什么更好的方法?

如果我没记错的话,以下方法应该有效

#student.rb
class Student
  has_many :assignments
  has_one :harry_potter_assigment, -> { where(book_id: Book.find_by_name('Harry Potter').id }, class_name: "Assignment"
end

您可以尝试这样定义它:

class Student < ActiveRecord::Base
  has_many :assignments

  def assignments_named(book_name)
    self.assignments.join(:book).where("books.name=?",name)
  end
end

现在查询:

student = Student.first
student.assignments_named('Harry Potter')

产生以下SQL:

SELECT "assignments".* FROM "assignments"
INNER JOIN "books" ON "books"."id" = "assignments"."book_id"
WHERE "assignments"."student_id" = 1 AND (books.name='Harry Potter')

它不是has_one关系。 对于给定的学生和书“哈利·波特”,可能有零个,一个或多个作业。

如果要使书名动态化,可以执行以下操作:

class Student
  has_many :assignments
  has_many :books, through: :assignments

  def book_by_name(book_name)
    books.find_by!(name: book_name)
  end
end

并这样称呼:

ron = Student.find_by(name: 'Ron')
harry_potter_book = ron.book_by_name('Harry Potter')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM