通过连接表的范围查询has_many

时间:2015-02-21 13:59:57

标签: ruby-on-rails activerecord

我目前在使用rails中的查询时遇到了困难。

我有两个通过has_many连接的模型:

基本设置:多本书可以有多种语言,其中一些语言是original_languages。

language.rb

class Language < ActiveRecord::Base  
  has_many :language_books
  has_many :books, through: :language_books
end

book.rb

class Book < ActiveRecord::Base  
  has_many :language_books
  has_many :languages, through: :language_books
end

language_book.rb

class LanguageBook < ActiveRecord::Base  
  belongs_to :language
  belongs_to :book

  def self.original_language
    where(original_language: true)
  end

end

数据库结构:

id | name

语言

id | name

language_books

book_id | language_id | original_language

如您所见,我的连接表不仅是一个连接表,还有一个附加属性(original_language)。

我想要的是以下内容:

我的视图中有一张桌子,我想要展示每本书。在此表中,我还有一个名为&#39; original_language&#39;的列,其中我只想显示该书的original_languages。 获取某本书的所有语言并不是一个问题,但我不知道如何只显示原始语言。

我不能选择更改数据库结构。例如,包括&#34; original_language&#34;直接在books表中的属性不起作用,因为我有时会有多种原始语言。

目前我的工作内容如下:

控制器:

@books = Books.all

查看:

<% @books.each do |book| %>
  <% book.languages.each do |lang| %>
    <%= lang.name %>
  <% end %>
<% end %>

这段代码显然显示了每本书的每种语言。 关于如何实现我想要的任何想法?

2 个答案:

答案 0 :(得分:1)

在我看来,你并没有把关系置于最佳位置,我认为original_language会更好地作为书中的id

class Book < ActiveRecord::Base
  has_many :language_books
  has_many :languages, through: :language_books
  belongs_to :original_language
end
class Language < ActiveRecord::Base
  has_many :language_books
  has_many :books, through: :language_books
end
class LanguageBook < ActiveRecord::Base
  belongs_to :books
  belongs_to :languages
end

如果您想坚持使用当前架构,可以添加与范围的附加关系

class Book < ActiveRecord::Base
  has_many :language_books
  has_many :languages, through: :language_books
  has_one :original_language, through: :language_books, class_name: 'Language', scope -> { where(original_language: true) }
end

然后在Book

中添加一个好的委托
delegate :name, to: :original_language, prefix: true, allow_nil: true

你的电话会变得像这样

<% @books.each do |book| %>
  <%= book.original_language_name %>
<% end %>

答案 1 :(得分:0)

我猜测original_language是一个布尔值。如果没有,请添加示例seeds.rb文件。

如果您无法更改表格结构(如果可能,您应该这样做),这是您的解决方案:

<% @books.each do |book| %>
  <%= book.language_books.where(original_language: true).first.language.name %>
<% end %>