这是我使用includes =>
的基本查询result = Table1.where(some_condition).includes(:table2).where(some_condition)
现在我可以双向访问table1列:
result[0]['table1_column'] ,
result[0].table1_column,
name = 'table1_column'
result[0].send(name)
上述所有作品实际上都包含这些列。 但是table2列仅在内存中通过急切加载,因此我无法通过以下方式访问它们:
result[0].table2_column ,
name = 'table2_column'
result[0].send(name)
以上都不起作用,我需要使用发送
来访问它们答案 0 :(得分:0)
result[0].table_2.table2_column
或者特别是因为您想使用.send()
,然后:
result[0].table_2.send('table_2_column')
我不确定这是否是标准,但据我所知,你不应该对待......
Table1.where(some_condition).includes(:table2).where(some_condition)
...好像它在SQL中返回类似结果(即结果的二维表),而是将结果视为Rails对象(模型而不是表)。请考虑以下事项:
result1 = Model1.where(some_condition)
puts result1.class
# => Model1::ActiveRecord_Relation
puts result1[0].class
# => Model1
puts result1[1].class
# => Model1
# ...
result2 = Model2.where(some_condition)
puts result2.class
# => Model2::ActiveRecord_Relation
puts result2[0].class
# => Model2
puts result2[1].class
# => Model2
# ...
result3 = Model1.includes(:model2).where(some_condition)
puts result3.class
# => Model1::ActiveRecord_Relation
puts result3[0].class
# => Model1
puts result3[1].class
# => Model1
# ...
result1
是Model1
的“列表”,与预期相同,result2
也是如此。但是,在result3
注意到即使它是一个“include”子句(LEFT OUTER JOIN),结果仍然会被视为Model1
,而不是“连接列”结果。< / LI>
鉴于你想要使用.send()
,如果你真的想要做...
result[0].send('table2_column')
......而不是......的标准方式。
result[0].table_2.send('table2_column')
然后您可以使用delegate
。但请注意,这是模型的全局配置,而不是查询结果特定的配置。
class Model1 < ApplicationRecord
belongs_to :model2
delegate :table2_column, to: :model2
end
然后你现在可以......
result3 = Model1.includes(:model2).where(some_condition)
puts result3[0].table2_column
# or specifically as per your requirement:
puts result3[0].send('table2_column')
答案 1 :(得分:0)
您无法使用includes
对象上的Table1
访问它们,为此您需要编写手动选择查询。
如果您考虑一下,您告诉AR从Table1
获取行(从而填充对象类型Table1的集合),并且您希望它包含在来自Table2
的对象列中没有意义。
如果您绝对需要这样做,可以使用ActiveRecord::Base.connection
执行手动查询:
results = ActiveRecord::Base.connection.exec_query 'SELECT table1.*, table2.* FROM table1 INNER JOIN table2 ON table1.pkey = table2.fkey WHERE condition;'
然后,您可以使用结果集来选择列:
results.first['column_from_table_2']