简体   繁体   English

Ruby on Rails-查询多个模型

[英]Ruby on Rails - Query Multiple Models

I created a ActiveRecord model that does not have a corresponding table in the database. 我创建了一个ActiveRecord模型,该模型在数据库中没有对应的表。 I want it to manage the application 'scoped' queries: 我希望它管理应用程序的“范围”查询:

class Meter <ActiveRecord::Base
  def self.daily_tests
    self.connection.execute(sanitize_sql(["SELECT b.*, m.*, i.* FROM bgtests AS b JOIN meals AS m ON b.user_id = m.user_id JOIN injections AS i ON i.user_id = m.user_id WHERE b.user_id = 2 AND m.user_id = 2 AND i.user_id = 2"]))
  end
end

The query executes however the result set brings back this: 查询执行,但是结果集返回此:

{"id"=>1, "value"=>712, "category"=>"basal", "time_of_day"=>"Before dinner", "comments"=>"Est et aut. Est maxime sunt. Dolor doloribus distinctio sed reprehenderit culpa. Autem ipsam atque modi dolor ut non. Aut dicta voluptate occaecati.", "user_id"=>2, "created_at"=>"2015-06-21 18:58:55.806367", "updated_at"=>"2015-06-21 18:58:55.806367", "name"=>"snack", "carbohydrates"=>142, "description"=>"Facere reiciendis non officia velit consequatur voluptas eum. Veritatis quia cumque. Dolor non eaque quod. Dignissimos quae aut eveniet sunt ea amet. Iste et aut unde consequatur quia commodi.", "num_of_units_taken"=>1.0, 0=>10, 1=>712, 2=>"smbg", 3=>"Before dinner", 4=>"Est et aut. Est maxime sunt. Dolor doloribus distinctio sed reprehenderit culpa. Autem ipsam atque modi dolor ut non. Aut dicta voluptate occaecati.", 5=>2, 6=>"2015-06-21 18:58:55.595625", 7=>"2015-06-21 18:58:55.595625", 8=>12, 9=>"snack", 10=>142, 11=>"Facere reiciendis non officia velit consequatur voluptas eum. Veritatis quia cumque. Dolor non eaque quod. Dignissimos quae aut eveniet sunt ea amet. Iste et aut unde consequatur quia commodi.", 12=>2, 13=>"2015-06-21 18:58:56.115615", 14=>"2015-06-21 18:58:56.115615", 15=>1, 16=>1.0, 17=>"basal", 18=>2, 19=>"2015-06-21 18:58:55.806367", 20=>"2015-06-21 18:58:55.806367"},

The initial key-values are return as column-value however it then switches and adds subsequent records as 5=>2 for example. 初始键值将作为列值返回,但是它随后进行切换并添加后续记录,例如5 => 2。

My question is how can I query these multiple models on the foreign_key 'user_id" and have the result set bring back all the results in the typical object notation specific to the model? 我的问题是如何在foreign_key'user_id'上查询这些多个模型,并使结果集以特定于该模型的典型对象表示法返回所有结果?

Most of the methods defined by the ActiveRecord query interface accept SQL string arguments in addition to other forms specified in the docs. ActiveRecord查询接口定义的大多数方法除了在文档中指定的其他形式外,还接受SQL字符串参数。 You can also arbitrarily chain these methods, and AR will combine to create a proper SQL. 您也可以随意链接这些方法,AR会结合起来创建一个合适的SQL。 When in doubt, use to_sql to view the SQL generated. 如有疑问,请使用to_sql查看生成的SQL。 Assuming bgtests corresponds to a model called Bgtest , you could for example do the following: 假设bgtests对应于一个名为Bgtest的模型,您可以例如执行以下操作:

Bgtest.select("b.*, m.*, i.*").from("bgtests b")
.joins("JOIN meals AS m ON b.user_id = m.user_id")
.joins("JOIN injections AS i ON i.user_id = m.user_id")
.where("b.user_id = 2 AND m.user_id = 2 AND i.user_id = 2")

Method chaining works this way because each method returns an ActiveRecord::Relation object that accepts the same ActiveRecord::QueryMethods methods as ActiveRecord::Base (which your models subclass). 方法链接以这种方式工作,因为每个方法都返回一个ActiveRecord :: Relation对象,该对象接受与ActiveRecord :: Base(模型子类)相同的ActiveRecord :: QueryMethods方法。 Ordering of the method calls is therefore arbitrary. 因此,方法调用的顺序是任意的。 The SQL is not actually executed until you attempt to extract a value from the relation, whether due to the console calling to_s or because you call each in a view. 直到您尝试从关系中提取值(无论是由于控制台调用to_s还是因为您在视图中调用了each值),SQL才会真正执行。

Note that the above can be greatly simplified (and much more "Rails-y") by defining the correct associations on the models. 请注意,通过在模型上定义正确的关联 ,可以大大简化上述操作(以及更多的“ Rails-y”)。 In particular, the classes Bgtest , Meal , and Injection would all apparently call belongs_to :user , and User would call has_many :bgtests , etc. You can then use has_many with :through option in other classes, eg Bgtest could call has_many :meals, through: user , etc. AR would then know to INNER JOIN based on referencing the association names alone: 特别是,类BgtestMealInjection显然都将调用has_many :bgtests belongs_to :user ,而User将调用has_many :bgtests等,然后可以在其他类Bgtest has_many:through选项一起使用,例如Bgtest可以调用has_many :meals, through: user等AR随后将知道INNER JOIN仅基于引用该协会的名称:

Bgtest.joins(:meals, :injections).where(user_id: 2)

or LEFT OUTER JOIN : LEFT OUTER JOIN

Bgtest.includes(:meals, :injections).where(user_id: 2)

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

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