如何验证has_many的唯一性:通过连接模型?

时间:2011-11-23 18:47:53

标签: ruby-on-rails

我有选民模式加入的用户和问题。用户可以对问题进行投票。他们可以向上或向下投票(在选民模型中记录)。首先,我希望能够阻止用户在一个方向上投票。其次,我想让用户投反对票。因此,如果他们投了票,他们仍然可以投票,这将取代上行投票。用户永远不能对问题进行两次投票。这是我的文件:

class Issue < ActiveRecord::Base
  has_many :associations, :dependent => :destroy

  has_many :users, :through => :associations

  has_many :voterships, :dependent => :destroy
  has_many :users, :through => :voterships

  belongs_to :app

  STATUS = ['Open', 'Closed']

  validates :subject, :presence => true,
                      :length => { :maximum => 50 }
  validates :description, :presence => true,
                          :length => { :maximum => 200 }
  validates :type, :presence => true
  validates :status, :presence => true

  def cast_vote_up!(user_id, direction)
    voterships.create!(:issue_id => self.id, :user_id   => user_id,
                                             :direction => direction)
  end
end


class Votership < ActiveRecord::Base
  belongs_to :user
  belongs_to :issue
end

class VotershipsController < ApplicationController
  def create
    session[:return_to] = request.referrer
    @issue = Issue.find(params[:votership][:issue_id])
    @issue.cast_vote_up!(current_user.id, "up")
    redirect_to session[:return_to]
  end
end

class User < ActiveRecord::Base
  authenticates_with_sorcery!

  attr_accessible :email, :password, :password_confirmation

  validates_confirmation_of :password
  validates_presence_of :password, :on => :create
  validates_presence_of :email
  validates_uniqueness_of :email

  has_many :associations, :dependent => :destroy
  has_many :issues, :through => :associations

  has_many :voterships, :dependent => :destroy
  has_many :issues, :through => :voterships
end

2 个答案:

答案 0 :(得分:11)

您可以将唯一性约束放在Votership模型上。您无需在关联本身上进行验证。

class Votership < ActiveRecord::Base
  belongs_to :user
  belongs_to :issue

  validates :issue_id, :uniqueness => {:scope=>:user_id}
end

这意味着用户只能对特定问题进行一次投票(向上或向下)。

答案 1 :(得分:0)

关系模型:

person.computers.merge(Account.administrators)

这就是它的名称

credData <- ReShapeAdCredSubset %>% group_by(CredentialQ, year) %>% summarise(vizCredPrcnt = (sum(credential_wIndiv, na.rm = TRUE) / (sum(credential_wAll, na.rm = TRUE)))) %>% ungroup() %>% group_by(CredentialQ) %>% summarize(meanVizCredPrcnt = mean(visCredPrcnt, na.rm = T)) %>% arrange(CredentialQ, year, desc(meanVizCredPrcnt))

我们可以使用ActiveRecord :: SpawnMethods #incin!更好地做到这一点!

{{1}}

参考:https://coderwall.com/p/9xk6ra/rails-filter-using-join-model-on-has_many-through