【问题标题】:Using :joins in Ruby on Rails 3在 Ruby on Rails 3 中使用 :joins
【发布时间】:2011-01-26 23:21:04
【问题描述】:

问候 我有 3 个数据库表:

类型 ID 名字

来源 ID 姓名 type_id

运营 ID source_id 评论 ...

和每个模型:

class Type < ActiveRecord::Base
  has_many :sources, :dependent => :destroy
end

class Source < ActiveRecord::Base
  belongs_to :type
  has_many :operations, :dependent => :destroy
end

class Operation < ActiveRecord::Base
  belongs_to :source
  default_scope :order => 'created_at DESC'
end

在 Operation#index 控制器中,我有获取数据的代码(由脚手架生成)

@operations = Operation.all

还有一块视图operations/index.html.erb也是脚手架生成的

<% @operations.each do |operation| %>
  <tr>
    <td><%= operation.source_id %></td>
    <td><%= operation.comment %></td>
  </tr>
<% end %>

现在我想使用 source.name 而不是 *operation.source_id*

我尝试过:

-将 operation.source_id 替换为 operation.sources.name # 不起作用

-尝试使用 :joins,但无法获取 Sources 表字段

irb(main):057:0> Operation.first( :joins => :source )
=> #<Operation id: 2088, source_id: 1, summ: 10.0, comment: "", created_at: "2011-01-01 07:39:45", updated_at: nil>

irb(main):063:0> Operation.first( :joins => 'INNER JOIN sources ON operations.source_id = sources.id' )
=> #<Operation id: 2088, source_id: 1, summ: 10.0, comment: "", created_at: "2011-01-01 07:39:45", updated_at: nil>

我必须如何正确使用 :joins 来获取附加字段? 或者还有另一种获取组合表数据的方法。

以及为什么在 operations/show.html.erb 中我可以使用 并成功获取 source。名称,但在*operations/index.html.er*b 中不能

【问题讨论】:

    标签: ruby-on-rails-3 activerecord join


    【解决方案1】:
    <% @operations.each do |operation| %>
      <tr>
        <td><%= operation.source.name %></td>
        <td><%= operation.comment %></td>
      </tr>
    <% end %>
    

    我还建议更改您的 #index 方法以使用 includes 语句以避免 N+1 情况(即为每个单独的操作的源运行单独的数据库查询)。

    @operations = Operation.includes(:source).all
    

    【讨论】:

    • 它不工作。控制台:irb(main):011:0* Operation.includes(:source).first => # 浏览器:nil:NilClass 的未定义方法“名称”
    • 在控制台中执行以下操作会给您带来什么:Operation.includes(:source).first.source.name?由于您在 nil 上获得了未定义的方法,这可能表明您有一些 Operation 未链接到任何源的对象。如果是这种情况,并且是故意的,您可能需要使用类似 &lt;%= operation.source ? operation.source.name : "No Source" %&gt; 的内容。
    • Operation.includes(:source).first.source.name 让我得到 Source.name。如何在我的视图中获取 source.name?这是我的答案中的解决方案。但我想知道如何使用您的方法获取 source.name
    • 该死的。我创建了新的 rails 应用程序,生成了 2 个相同的模型并向 DB 添加了一些记录,即使使用 @operations = Operation.all 也可以使用。谢谢你帮助我
    • 问题出在一些记录上,缺少一些来源。这种方法&lt;%= operation.source ? operation.source.name : "No Source" %&gt; 解决了我的问题。谢谢。
    【解决方案2】:

    已解决:

    操作#index

    @operations = Operation.all :joins => :source, :select => '*'
    

    操作/index.html.erb

    <% @operations.each do |operation| %>
      <tr>
        <td><%= operation.name %></td>
    ...
    

    【讨论】:

    • 它可能有效,但它并不是真正的“Rails 方式”。我建议像 dmarkow 描述的那样做。那真的应该管用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多