ROR:从多个表中选择

时间:2010-11-27 20:25:17

标签: ruby-on-rails activerecord has-and-belongs-to-many

我有两个表:兴趣和Link_ui(这是用于记录用户和兴趣)
我想输入用户ID并显示用户拥有的所有兴趣名称。

在Link_ui控制器中:

 def output
    @interests = LinkUi.find_by_sql [ 'SELECT interests.name FROM link_uis, interests
    WHERE link_uis.interest_id = interests.id AND link_uis.user_id=? ', params['user_id'] ]

输入页面:

<%= form_tag :action => 'output', :method => 'post' %>
  enter id.
  <%= text_field_tag ':user_id', '', 'size' => 30 %>

它没有任何结果,但我确信数据库中存在匹配的数据。如果我没有输入参数,只需设置link_uis.user_id = 1,就会出现:

your search are [#<LinkUi >, #<LinkUi >, #<LinkUi >, #<LinkUi >]

这有什么问题..

1 个答案:

答案 0 :(得分:4)

嗯, LinkUi 模型上的find_by_sql要求您返回link_uis表中的列,而您只选择interests.name。但是,你正在与ActiveRecord进行一些斗争。 :)

您通常希望避免使用find_by_sql,而是让ActiveRecord为您生成SQL。对你的例子来说,最重要的可能是联想。

我看到它的方式,你有一堆用户,以及一堆兴趣。您的 LinkUis 将这两者联系在一起( LinkUi 属于用户兴趣)。请随意纠正我;这是我从你的例子中收集到的业务逻辑。

这些类(我强调的名称)是您的模型,在app/models目录中定义。应该在这些类上定义它们之间的关联(关系)。


用户模型中使用简单关联开始:

class User < ActiveRecord::Base
  has_many :link_uis
end

在您的兴趣模型中:

class Interest < ActiveRecord::Base
  has_many :link_uis
end

然后将 LinkUi 模型连接在一起:

class LinkUi < ActiveRecord::Base
  belongs_to :user
  belongs_to :interest
end

现在,在任何用户的情况下,您可以通过简单地说user.link_uis.all和每个 LinkUi 来获取他/她的 LinkUis ,您可以将兴趣视为link_ui.interest。您可以告诉ActiveRecord尝试使用:include尽可能高效地一次性获取这两个,并使用标准Ruby collect方法获取 Interest 名称列表。然后它变成:

user = User.find params['user_id']
link_uis = user.link_uis.all(:include => :interest)
interest_names = link_uis.collect { |link_ui| link_ui.interest.name }

你可以更进一步;对于任何用户,您可以直接获得他/她的兴趣。一旦设置了上述关联,就可以将两个“步骤”折叠成一个,如下所示:

class User < ActiveRecord::Base
  has_many :link_uis
  has_many :interests, :through => :link_uis
end

这可以将这个例子变成这个单行:

interest_names = User.find(params[:user_id]).interests.collect { |i| i.name }