将SQL转换为Rails查询

时间:2012-10-26 14:09:13

标签: ruby-on-rails activerecord

如何将这个SQL语句写成'Rails方式'?

SELECT users.*, count(invitations.id) AS invitations_count 
FROM users
LEFT OUTER JOIN invitations ON invitations.sender_id = users.id
GROUP BY users.id
HAVING count(invitations.sender_id) < 5 AND users.email_address NOTNULL
ORDER BY invitations_count

我是否应该使用squeel gem进行这类查询?

2 个答案:

答案 0 :(得分:1)

如果您只想传输SQL,这是可用的:

User.find_by_sql("...")

但是,如果您使用命名(invitations.user_id)跟踪rails约定,并将邀请计数存储在用户上(并在添加邀请时更新它)而不是每次都进行连接,那么您可以执行此操作:

关于用户:

scope :emailable, where('users.email_address IS NOT NULL')
scope :low_invitations, where('users.invitation_count < 5')

然后查询具有5个以下邀请和电子邮件地址的用户,按邀请顺序​​排序:

@users = User.emailable.low_invitations.order('invitation_count asc')

然后使用以下内容访问用户的邀请:

@user.invitations
@user.invitations.count 
etc

对于上述内容,您必须向用户添加invitation_count col,将sender_id更改为user_id,并将一些范围添加到用户模型。您也可以使用连接来获取计数而不使用非规范化的invitation_count。

如果您打算使用rails,那么使用这些约定要比使用它们容易得多,您可能会发现设置一个小型实验应用程序并玩关系,以及阅读协会指南是值得的:

http://guides.rubyonrails.org/association_basics.html

答案 1 :(得分:0)

您需要为邀请和用户定义正确的模型,然后通过n * 1或n * n关系(通过belongs_to,has_many等)连接它们。然后,您将能够编写将在“引擎盖下”生成此类或类似查询的代码。

使用Rails时,你必须停止思考SQL并开始思考模型,视图,控制器。