如何在Ruby中编写复杂的查询

时间:2013-08-19 12:20:16

标签: ruby-on-rails activerecord

需要建议,如何在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'])

2 个答案:

答案 0 :(得分: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. 访问它们
  3. 这个查询并不是那么复杂,ActiveRecord关系使它更容易理解和维护。
  4. 我假设您正在使用旧数据库,这就是为什么您的列以这种方式命名的原因。如果我错了并且你为这个应用程序创建了这些表,那么你的生活将更容易(和传统),主键被称为id,你的时间戳被称为created_at和{{1 }}。
  5. 选项2(更好)

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

    updated_at

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

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

    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
    

    或者如果你想获得所有受托人的图像:

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

    选项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

答案 1 :(得分:0)

是的,find_by_sql可以使用,您也可以尝试:

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

或用于通用查询:

ActiveRecord::Base.connection.execute('...')