基于项目创建使用枚举设置默认角色
Setting Default Role using Enum based on Project creation
我有一个项目和一个关系模型来建立用户和项目之间的 'following' 关系。我在关系模型中使用枚举为 'Relationship' 建立了三个角色...他们是管理员、协作者和访问者。但是,我需要根据建立用户和项目之间关系的方式设置默认角色。需要以下简单场景:
(a) 创建项目的用户会自动关注该项目...创建项目时应将关系角色设置为 'Admin'
(b) 如果网站访问者只是导航到项目资料页面,他们可以单击 'Follow' 按钮建立关注关系...但是这应该将关系角色设置为 'Visitor'
关系模型:
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
关系控制者:
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
根据上述两种情况,为了将默认角色设置为 'admin' 或 'visitor',我需要对代码进行哪些更改?
如以上评论所述,我认为您 在创建 Relationship
时应明确说明 role
,因为角色在Relationship
class.
所固有的条件
现在,由于 Relationship
是您的 User
和 Project
模型之间 has many :through
关联的中间人,您不能简单地使用连接用户的标准方式使用 <<
的项目,但必须 显式 Relationship
构建中间人 ,包括您的自定义参数(例如角色)。
你的解决方案应该类似于 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!
方法的工作方式相同,但各自在关系中设置不同的角色。然后,您可以简单地从控制器中调用适当的,例如在创建项目时设置 'admin' 关系:
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关于:through协会的内容。
我有一个项目和一个关系模型来建立用户和项目之间的 'following' 关系。我在关系模型中使用枚举为 'Relationship' 建立了三个角色...他们是管理员、协作者和访问者。但是,我需要根据建立用户和项目之间关系的方式设置默认角色。需要以下简单场景:
(a) 创建项目的用户会自动关注该项目...创建项目时应将关系角色设置为 'Admin'
(b) 如果网站访问者只是导航到项目资料页面,他们可以单击 'Follow' 按钮建立关注关系...但是这应该将关系角色设置为 'Visitor'
关系模型:
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
关系控制者:
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
根据上述两种情况,为了将默认角色设置为 'admin' 或 'visitor',我需要对代码进行哪些更改?
如以上评论所述,我认为您 在创建 Relationship
时应明确说明 role
,因为角色在Relationship
class.
现在,由于 Relationship
是您的 User
和 Project
模型之间 has many :through
关联的中间人,您不能简单地使用连接用户的标准方式使用 <<
的项目,但必须 显式 Relationship
构建中间人 ,包括您的自定义参数(例如角色)。
你的解决方案应该类似于 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!
方法的工作方式相同,但各自在关系中设置不同的角色。然后,您可以简单地从控制器中调用适当的,例如在创建项目时设置 'admin' 关系:
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关于:through协会的内容。