[英]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). 我认为最终将需要使用某种数组方法(如果您想变得更复杂,则可以使用struct
或hash
)。
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
leads
和prospects
我这样称呼它:
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.