简体   繁体   English

Rails活动记录查询到字符串

[英]Rails active record query to string

When I have the AR query like this : 当我有这样的AR查询时:

MyModel.joins(:related_model).where('related_model.some_column = ?', 'somevalue')

If I used to_sql on the above code it would generate something like : 如果我在上面的代码上使用to_sql ,它将生成类似以下内容的代码:

"SELECT * FROM MY_MODEL INNER JOIN RELATED_MODEL ON RELATED_MODEL.SOME_ID = MY_MODEL.SOME_ID WHERE RELATED_MODEL.SOME_COLUMN = 'SOMEVALUE'"

I'm creating a slightly, or way more complex query, and I hate to duplicate code. 我正在创建一个稍微复杂的查询,而我讨厌重复代码。 Is there are way that I can get this part with some command to alter the generated SQL below? 有什么办法可以通过一些命令来更改下面的生成的SQL?

INNER JOIN RELATED_MODEL ON RELATED_MODEL.SOME_ID = MY_MODEL.SOME_ID WHERE RELATED_MODEL.SOME_COLUMN = 'SOMEVALUE'"
foo = MyModel.joins(:related_model).where('related_model.some_column = ?', 'somevalue').to_sql`

core_sql = foo.sub(/^SELECT * FROM MY_MODEL /,'')`

I think will end up needing to be a method of some sort with arrays (or a struct or hash if you want to get more complex). 我认为最终将需要使用某种数组方法(如果您想变得更复杂,则可以使用structhash )。

Using the table_name method to access the underlying table behind a model you could do something like this. 使用table_name方法访问模型背后的基础表,您可以执行以下操作。

def auto_joins (primary_model, related_models, values)
   search = primary_model + '.table_name'
   primary_table_name = eval(search)
   primary_id = primary_table_name + '_id'
   output_sql = "SELECT * FROM #{primary_table_name}"
   related_models.each do |model|
       search = model + '.table_name'
       table_name = eval(search)
       output_sql += " INNER JOIN #{table_name} ON #{table_name}.#{primary_id} = #{primary_table_name}.id "
   end
   output_sql += "WHERE 1 = 1 " #overcome no values passed in...
   values.each do |where|
        output_sql += "AND #{where}"
   end
   output_sql
end

And in my test database I had contact that had_many leads and prospects I called it like this: 在我的测试数据库中,我联系了had_many leadsprospects我这样称呼它:

auto_joins('Contact', ['Lead', 'Prospect'], ["contact.first_name = 'Brian'"])

and it generated this: 它产生了这个:

SELECT * FROM contacts 
  INNER JOIN leads ON leads.contacts_id = contacts.id  
  INNER JOIN prospects ON prospects.contacts_id = contacts.id 
  WHERE 1 = 1 AND contact.first_name = 'Brian'

If you wanted to take it further you could have a hash for {model: 'Contact', where: "first_name = 'Brian'"} and both the where and joins together based on that. 如果您想进一步介绍它,可以为{model: 'Contact', where: "first_name = 'Brian'"}加上哈希,并在此基础上将where和join结合在一起。

Edit Note: Evals are unsafe if you are exposing any of this to user input. 编辑说明:如果要将任何这些暴露给用户输入,则评估是不安全的。 You could find another way to access these models through activerecord and accomplish the same goal. 您可以找到另一种通过activerecord访问这些模型并实现相同目标的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM