使用Join in Rails 3进行搜索

时间:2010-10-20 11:52:13

标签: sql ruby-on-rails

我正在开发Rails 3中的一个小应用程序。在这个应用程序中,用户可以相互连接。我主要使用两个表来存储用户数据和关系。我想用firstname或lastname搜索这些表以获取用户的联系人。

表一 - 个人资料

在此表中,我存储了用户的名字,姓氏和ID。

表二 - 联系人

在此表中,我存储了用户的ID(profile_id)以及他所连接的用户的ID(friend_id)。

我使用以下查询,但无法获得正确的结果。

Profile.find_by_sql("SELECT * FROM contacts
              INNER JOIN profiles ON contacts.friend_id = profiles.id WHERE profiles.firstname = '#{@keyword}' OR  profiles.lastname = '#{@keyword}'")

问题是什么?如何更有效?

2 个答案:

答案 0 :(得分:1)

对您的查询“错误”有三个突出的问题。

首先,您使用find_by_sql进行相对简单的查询。如果您要在整个应用程序中编写这样的查询,那么您也可以使用PHP。

其次是你将查询参数传递给sql的方式。这将使您对SQL注入攻击敞开大门,因为输入未被转义。

使用内置的ActiveRecord方法可以解决这两个问题。正如其他一些答案所表明的那样,这是一个非常简单的重构。

我看到的第三个问题是没有使用外键的标准Rails命名约定。而不是Contacts.friend_id,它应该是Contacts.profile_id。这不是必需的,但是代码越传统,您需要与模型关系一起使用的“黑客”就越少。此规则唯一可接受的例外是,如果您要改进现有的数据库架构,但听起来不是这种情况。

我建议查看RailsGuides以获取有关标准约定的更多信息。

答案 1 :(得分:0)

你可以使用ActiveRecord的东西......

class Profile
  has_many :contacts, :foreign_key => 'friend_id', :class_name => 'Contact'
end

class Contact
end

Profile.joins(:contacts).where({:contacts => {:firstname' => 'Cyril', :lastname => 'Mougel'}).all