Activerecord has_many:通过多个模型

时间:2016-04-20 16:22:20

标签: ruby-on-rails ruby-on-rails-4 activerecord

我尝试使用@IBAction func buttonPressed(sender: UIButton) { if (someClause == true) { // Stay on ViewControllerA } else { performSegueWithIdentifier("showB", sender: AnyObject) } } override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { if (segue.identifier == "showB") { let _ = segue.destinationViewController as? ViewControllerB } } 访问来自给定用户的所有评论。查询将通过两个不同的模型,这两个模型可能都返回结果。我的关系设置如下:

user.comments

评论被确认属于参与者或组织者。

我不确定该怎么做。我试过了

class User < ActiveRecord::Base
  has_many :organisers
  has_many :participants
  has_many :comments, through: :participants / :organisers (see explenation below)
end

class Organiser < ActiveRecord::Base
  belongs_to :user
end

class Participant  < ActiveRecord::Base
  belongs_to :user
end

class Comment < ActiveRecord::Base
  belongs_to :organiser
  belongs_to :participant
end

has_many :comments, through: :participants
has_many :comments, through: :organisers

但最后一个不是铁轨。有没有正确的方法来做到这一点?谢谢!

6 个答案:

答案 0 :(得分:1)

has_many :comments, ->(user) {
  unscope(where: :user_id).
  left_joins(:organizer, :participant).
  where('organizers.user_id = ? OR participants.user_id = ?', user.id, user.id)
}

unscope 是去掉comments.user_id = ? 子句(定义{{​​1}} 关系时默认添加)。 has_manyleft_joins 上调用,因此您需要传入在 Comment 上定义的关系名称,因此在本示例中使用单数形式。

答案 1 :(得分:0)

由于我们无法使用has_many, through,因为comments来自organisersparticipants。我认为这里有两个解决方案:

解决方案#1 定义comments方法:

class User < ActiveRecord::Base
  def comments
    Comment.joins([{organiser: :user}, {participant: :user}])
           .where(users: {id: self.id})
  end
end

那么您查询评论的查询是:

User.first.comments

解决方案#2 Comment

中使用范围
class Comment < ActiveRecord::Base
  scope :from_user, -> (user) { 
    joins([{organiser: :user}, {participant: :user}]).where(users: {id: user.id}) 
  }
end

所以你的查询将是:

user = User.first
comments = Comment.from_user(user)

答案 2 :(得分:0)

你可以做一些简单的事情:

has_many :comments, -> { joins(:participant, :organizer) }, class_name: 'Comment'

应该返回所有包含参与者或管理者用户的评论,因为Rails往往会将joins默认为内部联接。您甚至可能不需要:class_name参数。

答案 3 :(得分:0)

我经过多次尝试后找到了解决方案。您可以在用户模型的最后一个has_many语句中使用带有param的范围:

has_many :comments, -> (user) {where organiser: user.organisers}, through: :participants

&#34;用户&#34; param表示调用comments方法的User对象。

答案 4 :(得分:0)

由于我们不能使用has_many,因此在这里一直到此,因为评论来自组织者和参与者。我只是认为这里有2种解决方案:

基本上,您仍然可以在此处通过Rails更改外键以自动接受self.id

User.first.comments

class User
  has_many :comments, -> { joins([{ organiser: :user }, { participant: :user }]) }, through: :participants, foreign_key: "users.id"
end

答案 5 :(得分:-1)

我相信您的关联会被混淆,因为user.com将不知道它是通过参与者还是组织者,所以最好的选择是声明两个不同的联接(具有不同的名称):

http://guides.rubyonrails.org/association_basics.html#self-joins