ActiveRecord在非默认值上加入嵌套关联

时间:2014-07-03 16:19:38

标签: ruby-on-rails ruby activerecord

在你提问之前,我无法控制在我正在使用的数据库中创建任何视图或连接表。

我在ActiveRecord文档中找到了您可以进行多级加入的方法:

12.2.4 Joining Nested Associations (Multiple Level)

Category.joins(articles: [{ comments: :guest }, :tags])
This produces:

SELECT categories.* FROM categories
  INNER JOIN articles ON articles.category_id = categories.id
  INNER JOIN comments ON comments.article_id = articles.id
  INNER JOIN guests ON guests.comment_id = comments.id
  INNER JOIN tags ON tags.article_id = articles.id

您可以在哪里指定要加入的内容

Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')

我想要做的是结合2

的东西
Client.joins('Inner Join addresses on addresses.client_name = client.name').joins('Inner Join state on state.abreviation = addresses.state_abreviation)

或在原始sql中

Select client.* from client 
Inner Join addresses on client.client_name = addresses.client_name
Inner Join state on addresses.state_abreviation = state.abreviation

如果我可以使用关联而不是连接来做到这一点,那就太棒了!:

class Category < ActiveRecord::Base
  has_many :articles
end

class Article < ActiveRecord::Base
  belongs_to :category
  has_many :comments
  has_many :tags
end

class Comment < ActiveRecord::Base
  belongs_to :article
  has_one :guest
end

class Guest < ActiveRecord::Base
  belongs_to :comment
end

class Tag < ActiveRecord::Base
  belongs_to :article
end

3 个答案:

答案 0 :(得分:3)

使用Arel:

c = Client.arel_table
a = Adress.arel_table
s = State.arel_table
query = Client.all.arel
         .join(a)
           .on(a[:client_name].eq(c[:client_name]))
         .join(s)
           .on(s[:abreviation].eq(a[:state_abreviation]))
Client.find_by_sql(query.to_sql)

答案 1 :(得分:0)

你可以使用'通过' 对于您的类别模型,这些将是这样的

class Category < ActiveRecord::Base
  has_many :articles
  has_many :comments, through: :articles
  has_many :tags, through: :articles
end

Category.last.tags
=> tags
Category.last.articles
=> articles

答案 2 :(得分:-2)

我找到了答案。您需要为表定义foreign_key,以便将其映射回来。

  belongs_to :addresses, foreign_key: 'state_abreviation'