我有两个模型:Users
和Posts
。我设置东西的方式,帖子属于所有者(即用户),并且还有许多参与者(即用户)。在我的用户模型中,我希望确保owner
永远不属于post
。我在前端完成了这项工作,但发现了比需要更多的代码。
这让我相信使用conditions
将是一个理想的解决方案。我已经看到了以这种方式使用的SQL条件,但并不确切知道为所有权方案完成此操作的最佳方法。建议?
class User < ActiveRecord::Base
has_many :posts
# belongs_to :posts, conditions: ...
end
class Post
has_many :participants, class_name: "User", foreign_key: "user_id"
belongs_to :owner, class_name: "User", foreign_key: "user_id"
end
答案 0 :(得分:2)
为了实现这一目标,我认为你需要第三种模式。如果按照以下方式进行设置,则应该有效:
用户模型:
class User < ActiveRecord::Base
has_many :posts # This is the other side of your owner association
has_many :user_posts # This is your link table for participants
has_many :participations, through: :user_posts, source: :user # These are the posts the user is a participant in
end
发布模型:
class Post < ActiveRecord::Base
has_many :user_posts, ->(p) { where.not(user_id: p.user_id) } # Here is your condition for the participants
has_many :participants, through: :user_posts, source: :user
belongs_to :owner, class_name: "User", foreign_key: "user_id"
end
UserPost模型:
class UserPost < ActiveRecord::Base
belongs_to :user
belongs_to :post
end
正如@ Oxynum的答案所表明的那样,您还应该考虑在UserPost模型中进行验证,以防止参与者如果他也是所有者而被保存:
validate :participant_cannot_be_owner
def participant_cannot_be_owner
if user == post.try(:owner)
errors.add(:user_id, "can't be the owner of the post")
end
end
答案 1 :(得分:1)
首先,您的关联中可能存在错误,因为您似乎需要参与者关系的连接表。 您应该使用http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association has_many通过协会。
这样的事情:
class User < ActiveRecord::Base
has_one :owned_post, class_name: "Post", foreign_key: :owner_id
has_many :participations
has_many :posts, through: :participations
end
class Participation < ActiveRecord::Base
belongs_to :post
belongs_to :participant, class_name: "User"
end
class Post < ActiveRecord::Base
belongs_to :owner, class_name: "User"
has_many :participants, through: :participations
end
如果您拥有此模型,则可以对参与模型使用验证,以防止所有者成为参与者。使用自定义验证:http://guides.rubyonrails.org/active_record_validations.html#performing-custom-validations
class Participation < ActiveRecord::Base
belongs_to :post
belongs_to :participant, class_name: "User"
validate :participant_is_not_the_owner
def participant_is_not_the_owner
if participant == post.owner
errors.add(:participant, "can't be the owner")
end
end
end