【问题标题】:Rails associations nestingRails 关联嵌套
【发布时间】:2013-10-23 20:03:24
【问题描述】:

我有三个由非 Rails 应用程序创建的表。以下模型只是表的关联。

class Client < ActiveRecord::Base
  has_many :programs
  has_many :locations, :through => :programs
end

class Program < ActiveRecord::Base
  belongs_to :location
  belongs_to :client
end

class Location < ActiveRecord::Base
  has_many :programs
  has_many :clients, :through => :programs
end

我想要一种更简单的方法来按位置列出客户的所有程序。

我认为下面的代码会起作用,但它会返回该位置的所有程序,这完全有道理。

@client.locations.each do |location|
  <h2>location.name</h2>
  <ul>
   location.programs.each do |program|
   <li>program.name</li>
  end
  </ul>
end

我正在使用

@client.locations.each do |location|
      <h2>location.name</h2>
      <ul>
       Program.where(:location_id => location.id, :client_id => @client.id).each do |program|
       <li>program.name</li>
      end
      </ul>
    end

但这违反了 MVC 原则,而且很丑陋。

我不确定如何优雅地编写此代码,希望能提供意见。

【问题讨论】:

    标签: ruby-on-rails activerecord rails-models


    【解决方案1】:

    您可以使用includes 方法来预加载数据。此外,在这种情况下使用 include 将创建一个连接查询,该查询将仅获取与位置和客户端相关的那些程序。

    @client.locations.includes(:programs).each do |location|
      <h2>location.name</h2>
      <ul>
        location.programs.each do |program|
          <li>program.name</li>
        end
      </ul>
    end
    

    尽管您应该避免在视图文件中使用数据库查询。因此,您可以将@locations = @client.locations.includes(:programs) 移动到您的控制器操作中,并在视图中使用@locations 来维护结构。

    【讨论】:

    • 使用 includes(:programs) 仍然会返回与该位置相关的所有客户端的所有程序
    【解决方案2】:

    你可以这样做

    @client.programs.each do |program|
      <h2>program.location.name</h2>
      <ul>
          <li>program.name</li>
        end
      </ul>
    end
    

    【讨论】:

    • 那还不够。我正在寻找的是

      USA

      program_1 program_3

      Canada

      program_2 program_4
    • 然后你可以@client.locations.each 做|location|

      location.name

        location.programs.find_by_client(client).each do |program|
      • program.name
      • end
      end made find_by_client scope in program model
    • 这个建议会有n+1个查询问题。所以我们需要在这里使用急切加载。
    • 这可能就是我要找的。 Manoj,你能举个简单的例子吗?
    猜你喜欢
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多