Rails SQL query builder… Or ActiveRecord query builder

后端 未结 3 1723
终归单人心
终归单人心 2020-12-19 11:21

I need to run sql query like

sql = \'SELECT * FROM users WHERE id != \' + self.id.to_s + \' AND id NOT IN (SELECT artner_id FROM encounters WHERE user_id =          


        
3条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-19 12:09

    Here's the same query cast into rails AREL terms. It's not pretty yet -- it's a complicated query in general.

    User.where("id = ? AND "
               "id NOT IN (SELECT artner_id FROM encounters WHERE user_id = ?) AND " +  
               "id NOT IN (SELECT user_id FROM encounters WHERE partner_id = ? AND predisposition = ? ) AND " + 
                "cfg_sex = ? AND cfg_country = ? AND cfg_city = ?)", 
                self.id, self.id, self.id, Encounter::Negative, 
                self.sex, self.country, self.city).order(" rand() ").limit(1)
    

    (I've not tested this, so it's possible there could be typo's in it.)

    I'd recommend a couple things:

    When you have complex where clauses they can be chained together and AREL will put them back together generally pretty well. This allows you to use scopes in your model classes and chain them together.

    For example, you could do this:

    User < ActiveRecord::Base
      self.def in_city_state_country(city, state, country)
        where("cfg_sex = ? AND cfg_country = ? AND cfg_city = ?", city, state, country)
      end
      self.def is_of_sex(sex)
        where("cfg_sex = ?", sex)
      end
    end
    

    Then you could rewrite these portions of the query this way:

    User.is_of_sex(user.sex).in_city_state_country(user.city, user.state, user.country)
    

    and so on.

    Breaking the queries down into smaller parts also makes it easier to test specific pieces of it with your rspecs. It results in more modular, maintainable code.

    For more details, check out the Rails Guide - Active Record Query Interface

提交回复
热议问题