Rails控制器变量和复杂关系

时间:2012-08-06 23:06:53

标签: ruby-on-rails ruby relational-database

假设我们在Rails应用程序中有以下场景:

Users有很多WebsitesWebsites有很多Simulations(同样,Websites属于UsersSimulations }属于Websites)。

现在问题是,如何在用户显示页面上显示所有用户模拟的列表?

我的第一个尝试是在Users Controller中定义以下内容:

def show
  @user = User.find(params[:id])
  @websites = @user.websites
  @simulations = @user.websites.simulations
end

然后在<%= render @simulations %>中使用Users Show Page,但当我访问localhost:3000时,会为[]:Array`提供NoMethodErrorundefined method模拟。< / p>

那么如何在我的User Controller中创建一个变量,该变量包含属于特定Simulations的{​​{1}}的所有Websites

非常感谢任何和所有帮助!

3 个答案:

答案 0 :(得分:2)

class User < ActiveRecord::Base
  has_many :websites
  has_many :simulations, :through => :websites
end

现在您可以使用@simulations = @user.simulations并获取所有用户的模拟

答案 1 :(得分:0)

使用Erez的回答


你问过它 - 我不知道ruby,但@websites中的每个网站都应该包含一个有模拟的字段。

这就是你正在做的事情。

1 - 您接受用户,单个对象并获取其网站。凉。用户看起来像这样(在伪代码中):

 Object @user
    {
         Array[] websites = [(Website)site1, (Website)site2];
    } 

好的,那很酷。所以user.websites应该返回一系列网站。

2 - 您尝试从网站获取模拟。一个网站可能看起来像这样:

 Object @website
    {
         Array[] simulations = [(Simulation)sim1, (Simulation)sim2];
    } 
嗯,为什么不起作用?好吧,让我们分解你正在做的事情:

@user.websites.simulations

您正在使用websites这是一个数组,并尝试引用属于website类型而非array类型的变量。 @user.websites是一个包含网站的数组对象,而不是网站本身。你想要的是获得@website.simulations,而不是websites.simulations

所以第一步是建立一个网站。这很简单 - 一种方法是尝试从用户的网站数组中获取网站。

@User.websites[0] <-- may not be syntactically correct; I don't know ruby.

现在,如果您想要获取所有网站,请使用循环迭代它们并将它们推送到新阵列。再次以伪代码:

@all_simulations = new Array();
for(@i=0;@i<count(@user.websites);@i++) //first loop through the websites
{
     for(@q=0;@q<count(@user.websites[@i].simulations);@q++) //then loop through the simulations
     {
           @all_simulations.push(@user.websites[@i].simulations[@q]); //push the simulation into @all_websites
     }
}

我们在这里做的是我们进入user.websites数组中的每个网站,然后从该网站获取每个模拟并将其放入我们的@all_simulations变量中。如果你理解这个概念,你应该能够将这个逻辑转换成有效的ruby。

答案 2 :(得分:0)

在您的用户模型中添加此方法。这将产生2个查询,但仍然更好,然后加入ruby代码中的模拟。

def websites_simulations
  Simulation.where(website_id: website_ids)
end