2016-03-21 10 views
1

私は、プロジェクトとリレーションシップモデルを使用して、ユーザーとプロジェクトの間に次の関係を確立しています。私は関係モデルの列挙型を使って 'Relationship'の3つの役割を確立しました。彼らは管理者、協力者、訪問者です。しかし、ユーザーとプロジェクトの関係が確立される方法に基づいてデフォルトの役割を設定する必要があります。次の簡単なシナリオが必要とされていますプロジェクトの作成に基づいて列挙型を使用して既定のロールを設定する

は、(a)のプロジェクトを作成するユーザーは、自動的にプロジェクト以下の通りです...関係の役割は、プロジェクトの作成時に「管理者」に設定する必要があります

(B)

:サイトへの訪問者は、単にプロジェクトのプロフィールページに移動した場合、彼らは次のような関係を確立するためのボタンを「フォロー」...しかし、これは「ビジター」

関係モデルとの関係の役割を設定する必要がありますクリックすることができます

class Relationship < ActiveRecord::Base 
    belongs_to :follower, class_name: "User" 
    belongs_to :followed, class_name: "Project" 
    validates :follower_id, presence: true 
    validates :followed_id, presence: true 

    enum role: [:admin, :collaborator, :visitor] 
    after_initialize :set_default_role, :if => :new_record? 

    def set_default_role 
    self.role ||= :admin 
    end 
end 

Re lationshipsコントローラ:

class RelationshipsController < ApplicationController 
    before_filter :authenticate_user! 

    def create 
    @project = Project.find(params[:relationship][:followed_id]) 
    current_user.follow!(@project) 
    # relationship.visitor! View railsapps documentation for devise pundit#roles 
    redirect_to @project 
    end 

    def destroy 
    @project = Project.find(params[:id]).followed 
    current_user.unfollow!(@project) 
    redirect_to @project 
    end 

    private 

    def relationship_params 
    params.require(:relationship).permit(:followed_id, :follower_id) 
    end 

プロジェクトコントローラー

class ProjectsController < ApplicationController 
    before_filter :authenticate_user!, only: [:create, :new, :edit, :update, :delete, :followers] 

def create 
    @project = current_user.own_projects.build(project_params) 
    if @project.save 
     if params[:project][:projectimage].present? 
     render :crop 
     else 
     flash[:success] = "You've successfully created a project..." 
     redirect_to @project 
     end 
    else 
     render 'new' 
    end 
    end 

    def update 
    @project = Project.find(params[:id]) 
    if @project.update_attributes(project_params) 
     if params[:project][:projectimage].present? 
     render :crop 
     else 
     flash[:success] = "Project Created" 
     redirect_to @project 
     @project.followers << current_user #this establishes the following relationship as soon as a new project is created between user/project 
     end 
    else 
     render 'edit' 
    end 
    end 

end 

ユーザーモデル:

class User < ActiveRecord::Base 
    has_many :own_projects, :class_name=>'Project' 

    has_many :projects 
    has_many :relationships, foreign_key: "follower_id", dependent: :destroy 

    has_many :followed_projects, through: :relationships, source: :followed 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    def following?(some_project) 
    relationships.find_by_followed_id(some_project.id) 
    end 

    def follow!(some_project) 
    self.relationships.create!(followed_id: some_project.id) 
    relationship.visitor! 
    end 

end 

私はどちらかの「管理者」にデフォルトのロールを設定するために、自分のコードに変更する必要がありますまたは上記の2つのシナリオに基づいて「ビジター」ですか?

+1

新しい「Relationship」を作成するときに 'role'を指定するのはなぜですか?異なる条件(関係の外部)で異なる場合、なぜデフォルト値を気にしますか? – BoraMa

+0

あなたが言及しているように、after_initializeとset_default_roleを削除した場合(とちょうどenumロールを残しました:[:admin、:collaborator、visitor] ...新しいプロジェクトのために、作成されていますか?プロジェクトコントローラまたはリレーションシップコントローラの作成アクションでは? thx – BB500

+1

はい、そういう意味です。基本的に関係が作成される場所であれば、関連する「ロール」を設定することができます。 'user'の' follow! 'メソッド:' self.relationships.create!(follow_id:some_project.id、role::visitor) 'やコントローラの中で実行されます。 – BoraMa

答えて

1

上記のコメントで述べたように、私はあなたのRelationship秒を作成する際に役割がRelationshipクラスに固有でない条件では異なるので、あなたを明示的に、roleを述べるべきだと思います。 Relationshipが仲介があなたのUserProjectモデル間has many :through関連しているよう

さて、あなたは単にあなたのカスタムなどの仲介Relationship明示的を構築<<を使用しますが持っているプロジェクトにユーザーを接続するための標準的な方法を使用することはできませんparams(ロールなど)

ユアーズの溶液を1 posted hereに類推すべきである:

class Project < ActiveRecord::Base 
    has_many :relationships, foreign_key: :followed_id, dependent: :destroy 
    has_many :users, through: :relationships 
end 

class User < ActiveRecord::Base 
    has_many :relationships, foreign_key: :follower_id, dependent: :destroy 
    has_many :projects, through: :relationships 

    # this will create the relationship association with the 'visitor' role 
    def follow_project!(some_project) 
    self.relationships.create!(followed_id: some_project.id, role: :visitor) 
    # I think you can even omit the ids here and work with objects: 
    # self.relationships.create!(followed: some_project, role: :visitor) 
    end 

    # this will create the relationship association with the 'admin' role 
    def administrate_project!(some_project) 
    self.relationships.create!(followed: some_project, role: :admin) 
    end 

    # this will create the relationship association with the 'collaborator' role 
    def collaborate_on_project!(some_project) 
    self.relationships.create!(followed: some_project, role: :collaborator) 
    end 
end 

class Relationship < ActiveRecord::Base 
    belongs_to :follower, class_name: "User" 
    belongs_to :followed, class_name: "Project" 

    enum role: [:admin, :collaborator, :visitor] 
end 

follow_administrate_collaborate_on_project!方法は、同じように動作するが、関係の各セットの異なる役割。その後、あなたは単にプロジェクトを作成するときの例では、「管理者」の関係を設定するために、コントローラから適切なものを呼び出すことができます。

class ProjectsController < ApplicationController 

    def create   
    # ideally you should wrap multiple separate saves in a transaction so that 
    # either they all succeed or all fail 
    Project.transaction do 
     # this creates a barebone project, without any association 
     @project = Project.create!(project_params) 
     # this associates the project to the current user with admin role 
     current_user.administrate_project!(@project) 
     # ...     
    end 
    end 

end 

も上rails guidesを必ずお読みください:慎重団体を通じて。

+0

あなたの援助のために多くのボラに感謝します。 – BB500

関連する問題