【问题标题】:Rails: how to join two models through two different relations?Rails:如何通过两个不同的关系加入两个模型?
【发布时间】:2018-02-10 16:39:09
【问题描述】:

我有两个模型:Saft(杂志)和 Keyword。每个“Saft”都由一系列关键字定义,但也有一个标题,它始终是其关键字之一。 Saft 和 Keyword 模型通过 HABTM 连接表连接,以便提取所有关键字,现在我也尝试将标题从关键字表中提取到 saft/show.html.erb 上。我正在尝试使用 class_name 选项来提取标题。因此我创建了 Edition 模型。

class Saft < ActiveRecord::Base
#  attr_accessible :colour, :cover_alt, :description, :number, :short
  has_and_belongs_to_many :keywords, :join_table => "safts_keywords"
  has_one :title, :through => :edition, :class_name => "keyword"
  has_one :edition
end

class Keyword < ActiveRecord::Base
#  attr_accessible :word, :description
  has_and_belongs_to_many :safts, :join_table => "safts_keywords"
  belongs_to :issue, :through => :edition, :class_name => "saft"
  belongs_to :edition
end

class Edition < ActiveRecord::Base
#  attr_accessible :saft_id, :keyword_id
  belongs_to :title
  belongs_to :issue
end

class SaftsController < ApplicationController 
  def show
    @saft = Saft.find(params[:id])
  end

show.html.erb
    <%= @saft.title.upcase %>

我收到以下错误:

Started GET "/safts/2" for 127.0.0.1 at Sat Feb 10 17:31:28 +0100 2018
Connecting to database specified by database.yml
Processing by SaftsController#show as HTML
  Parameters: {"id"=>"2"}
  Saft Load (1.8ms)  SELECT `safts`.* FROM `safts` WHERE `safts`.`id` = ? LIMIT 1  [["id", "2"]]
  Image Load (0.3ms)  SELECT `images`.* FROM `images` WHERE `images`.`saft_id` = 2
  Rendered safts/show.html.erb within layouts/public (35.0ms)
Completed 500 Internal Server Error in 103ms

ActionView::Template::Error (uninitialized constant Saft::keyword):
    29:                 </div>
    30:                 <div class="saft_box col-content">
    31:                     <div class="saft_keyword">
    32:                         <strong><%= @saft.title.upcase %></strong>
    33:                     </div>
    34:                     <div class="saft_description">
    35:                         <p><%= @saft.description %></p>
  app/views/safts/show.html.erb:32:in `_app_views_safts_show_html_erb___758994895_2167416580'

我怎样才能让它工作?

当取消注释 @saft.title.upcase 时,此实现也破坏了 Saft 关键字关联,我通过取消注释关键字模型中的 belongs_to :issue 部分再次开始工作。

【问题讨论】:

  • title 不是表中的字段,因为它是一个引用,所以 @saft.title.upcase 是错误的(大写形式适用于字符串)。什么是titleedition belongs_to title,但您没有 Title 模型。你有很多不必要的attr_accessible。您不需要为数据库中的字段包含attr_accessible。仅适用于未保存在数据库中的字段。
  • @Pablo 你说得对,title 不是关键字表中的字段,但应该是关键字的别名。我需要一种以两种方式访问​​关键字表的方法:一次提取所有关联的关键字,一次只提取特定的关键字。我需要 attr_accessible 才能在开发中播种我的初始数据集。
  • 你的版本模型有belongs_to :title 和belongs_to :issue。这些模型存在吗?我也不明白需要 attr_accessible。如果是表中的字段,则不需要。
  • @Pablo 我需要 attr_accessible 以便能够通过 seed.rb 从 yaml 文件中播种我的开发数据库。当我不声明它们时,我的种子不会通过并且 db:reset 会抛出:“无法批量分配受保护的属性:description,keyword_id,short,cover_alt,color”
  • @Pablo 我没有titleissue 模型。我在 stackoverflow 上找到了另一个帖子:Rails: Multiple Join tables between the same two models,也有类似的问题。从那里我了解到我可以通过class_name option 声明别名以建立第二个关系,但我可能错了。

标签: mysql ruby-on-rails ruby-on-rails-3


【解决方案1】:

模型的一些变化:

class Saft < ActiveRecord::Base
  #You don't need attr_accessible for fields in safts table
  has_and_belongs_to_many :keywords, :join_table => "safts_keywords"

  #The specific keyword that acts as title. 
  #You need a new field in safts table named title_id which references to a Keyword. 
  belongs_to :title, class_name => "Keyword", :foreign_key => 'title_id'
end

class Keyword < ActiveRecord::Base
  #You don't need attr_accessible for fields in keywords table
  has_and_belongs_to_many :safts, :join_table => "safts_keywords"
end

要获得 Saft 头衔,请使用 @saft.title.word.upcase if @saft.title

我认为对于 OP 中的用例,您的模型不需要任何其他内容。

【讨论】:

  • 非常感谢!!!它非常有效!我从那时开始,但不知道 class_name 选项并切换到附加版模型。 belong_to :title 对我来说也是新的。我会尝试使用has_one。我将在生产中删除 attr_accessible,但在开发过程中需要它,否则我将无法为我的测试数据集播种。再次非常感谢您。
猜你喜欢
  • 1970-01-01
  • 2014-08-10
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多