1

需要建议,如何在 Ruby 中编写复杂的查询。

在 PHP 项目中查询:

    $get_trustee = db_query("SELECT t.trustee_name,t.secret_key,t.trustee_status,t.created,t.user_id,ui.image from trustees t 
                             left join users u on u.id = t.trustees_id
                             left join user_info ui on ui.user_id = t.trustees_id
                             WHERE t.user_id='$user_id' AND trustee_status ='pending'
group by secret_key
ORDER BY t.created DESC")

我对 Ruby 的猜测:

get_trustee = Trustee.find_by_sql('SELECT t.trustee_name, t.secret_key, t.trustee_status, t.created, t.user_id, ui.image FROM trustees t
        LEFT JOIN users u ON u.id = t.trustees_id
        LEFT JOIN user_info ui ON ui.user_id = t.trustees_id
        WHERE t.user_id = ? AND
              t.trustee_status = ?
        GROUP BY secret_key
              ORDER BY t.created DESC',
              [user_id, 'pending'])
4

2 回答 2

4

选项 1(好的)

你是说 Ruby 和 ActiveRecord 吗?你在使用 ActiveRecord 和/或 Rails 吗?#find_by_sql是存在于 ActiveRecord 中的方法。此外,在这个查询中似乎不需要用户表,但也许你遗漏了一些东西?无论哪种方式,我都会将它包含在我的示例中。如果您没有正确设置关系,则此查询将起作用:

users_trustees = Trustee.
    select('trustees.*, ui.image').
    joins('LEFT OUTER JOIN users u ON u.id = trustees.trustees_id').
    joins('LEFT OUTER JOIN user_info ui ON ui.user_id = t.trustees_id').
    where(user_id: user_id, trustee_status: 'pending').
    order('t.created DESC')

此外,请注意此解决方案的一些事项:

  1. 我还没有找到一种超级优雅的方法来从返回的 ActiveRecord 对象中获取连接表中的列。您可以通过以下方式访问它们users_trustees.each { |u| u['image'] }
  2. 这个查询实际上并没有那么复杂,ActiveRecord 关系使它更容易理解和维护。
  3. 我假设您使用的是旧数据库,这就是您的列以这种方式命名的原因。如果我错了,并且你为这个应用程序创建了这些表,那么你的生活会更容易(和传统),因为你的主键被调用id,你的时间戳被调用created_atupdated_at.

选项 2(更好)

如果您正确设置了 ActiveRecord 关系和类,则此查询会容易得多:

class Trustee < ActiveRecord::Base
  self.primary_key = 'trustees_id' # wouldn't be needed if the column was id
  has_one :user
  has_one :user_info
end

class User < ActiveRecord::Base
  belongs_to :trustee, foreign_key: 'trustees_id' # relationship can also go the other way
end

class UserInfo < ActiveRecord::Base
  self.table_name = 'user_info'
  belongs_to :trustee
end

如果性能不是最重要的,您的“查询”现在可以成为 ActiveRecord 的优点。Ruby 的约定首先是可读性,如果内容开始扩展,则稍后重新组织代码。

假设您想获得受托人的形象:

trustee = Trustee.where(trustees_id: 5).first
if trustee
  image = trustee.user_info.image
  ..
end

或者,如果您想获取所有受托人的图像:

Trustee.all.collect { |t| t.user_info.try(:image) } # using a #try in case user_info is nil

选项 3(最佳)

受托人似乎只是某种特殊情况的用户。如果您不介意重组表以进一步简化,您可以使用 STI。

这可能超出了这个问题的范围,所以我只会将您链接到有关此的文档:http ://api.rubyonrails.org/classes/ActiveRecord/Base.html请参阅“单表继承”。另请参阅他们从 Martin Fowler 链接到的文章 ( http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html )

资源

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

于 2013-08-19T12:58:11.213 回答
0

是的,find_by_sql会工作,你也可以试试这个:

Trustee.connection.execute('...')

或对于通用查询:

ActiveRecord::Base.connection.execute('...')
于 2013-08-19T12:56:31.387 回答