我有两个表:兴趣和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 >]
这有什么问题..
答案 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 }