2011-11-23 4 views
7

私は、ユーザーと問題に投票人数モデルが加わりました。ユーザーは問題に投票できます。彼らは上下に投票することができます(投票券モデルに記録されています)。まず、ユーザーが複数の票を1つの方向に投じるのを防ぐことができるようにしたい。第二に、私はユーザーが反対の投票をすることを許可したい。彼らが投票した場合、議決権を代理することができるはずです。ユーザーは決して問題に2度投票することはできません。ここにファイルがあります:has_many:through joinモデルの一意性を検証するにはどうすればよいですか?

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 

答えて

10

Votershipモデルに一意制約を設定します。アソシエーション自体にバリデーションを入れる必要はありません。

これは、特定の問題(上または下)に対してユーザーが1回のみ投票できることを意味します。

+0

こんにちは、これは動作しますが、結合テーブルで重複したエントリを追加するとき、それは 'のActiveRecord :: ValidateError'例外が発生します。レコードを関連付けたり、例外を発生させずに失敗するにはどうすればよいでしょうか?ありがとう –

+0

検証エラーを発生させるのではないですか? 1つの問題につき1つの票しか必要ない場合は、前の票を削除して(新しい票に置き換えて)、またはエラーが発生したときに救済して何をすべきかを決定する必要があります。重複したエントリの検証に失敗したように思えます。 – jefflunt

+0

はい、私はレールに慣れていないので、私は尋ねます。例外を救済するためのよりよい方法(例外を発生させない '<<'のようなもの)があるかどうか疑問に思いました。回答 –

0

関係モデル:

class Person 
    has_many :accounts 
    has_many :computers, through: :accounts 
end 

class Account 
    belongs_to :person 
    belongs_to :computer 

    scope :administrators, -> { where(role: 'administrator') } 
end 

class Computer 
    has_many :accounts 
    has_many :people, through: :accounts 
end 

これは、我々はActiveRecordの:: SpawnMethods#がマージ使用してこの優れた操作を行うことができ、それが

person.accounts.administrators.map(&:computer)

と呼ばれる方法です!

person.computers.merge(Account.administrators)


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

関連する問題