Rails 4 has_many :through association: use Devise current_user in other parent model after_create 回调
Rails 4 has_many :through association: use Devise current_user in other parent model after_create callback
我有三个模型,具有 has_many :through
关联:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
连接 Administration
模型具有以下属性:
id
user_id
calendar_id
role
这是我当前的路线:
devise_for :users, :path => 'account'
resources :users do
resources :calendars
end
更新
这里是 Calendars#create
代码:
def create
@user = current_user
@calendar = @user.calendars.create(calendar_params)
respond_to do |format|
if @calendar.save
format.html { redirect_to user_calendar_path(@user,@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
每当 user
创建一个新的 calendar
时,我想为这个特定的 user
分配一个 role
— 在 administration
连接模型中 — "Owner".
我认为最好的方法是在 calendar
模型中使用 after_create
回调,如下所示:
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
after_create :set_default_role
protected
def set_default_role
current_user.calendar.role = "Owner"
end
end
但是,当我继续尝试创建新日历时,出现以下错误:
NameError in CalendarsController#create
undefined local variable or method `current_user' for #<Calendar:0x007f88f8f26998>
Extracted source (around line #10):
def set_default_role
current_user.calendar.role = "Owner"
end
end
经过一些研究,我发现 this question on Quora 的答案如下:
It is not good practice for the model to directly have knowledge of
the current user; this is an application 'state' or session related
issue. The controllers should be managing the current user.
我不得不说我有点困惑:一般原则是通过将逻辑放在模型中来保持控制器瘦身。但是,上面的答案建议做相反的事情,因为模型不应该知道当前用户。
所以,回到我最初的问题:当用户创建新日历时,我如何为他定义默认角色?
我应该使用 after_create
回调,使用其他东西而不是 current_user
来获取他的 id
,还是使用完全不同的解决方案?
更新:
该模型没有 current_user。从日历模型中删除 set_default_role 并添加到管理模型:
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
before_create :set_default_role
def set_default_role
self.role = "Owner"
end
end
将此添加到 CalendarsController 创建操作:
@calendar.administrations.first.role = 'Owner'
而且我认为它会起作用。
这是我最后做的。
首先,在User
模型中,我定义了如下方法:
def set_default_role(calendar_id, role)
self.administrations.find_by(calendar_id: calendar_id).update(role: role)
end
然后,我更新了Calendars#Create
如下:
def create
@user = current_user
@calendar = @user.calendars.create(calendar_params)
respond_to do |format|
if @calendar.save
current_user.set_default_role(@calendar.id, 'Owner')
format.html { redirect_to user_calendar_path(@user,@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
现在,每当 user
创建一个新的 calendar
时,如果保存了新的 calendar
,则 current_user
默认分配给 role
所有者。
我有三个模型,具有 has_many :through
关联:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
连接 Administration
模型具有以下属性:
id
user_id
calendar_id
role
这是我当前的路线:
devise_for :users, :path => 'account'
resources :users do
resources :calendars
end
更新
这里是 Calendars#create
代码:
def create
@user = current_user
@calendar = @user.calendars.create(calendar_params)
respond_to do |format|
if @calendar.save
format.html { redirect_to user_calendar_path(@user,@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
每当 user
创建一个新的 calendar
时,我想为这个特定的 user
分配一个 role
— 在 administration
连接模型中 — "Owner".
我认为最好的方法是在 calendar
模型中使用 after_create
回调,如下所示:
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
after_create :set_default_role
protected
def set_default_role
current_user.calendar.role = "Owner"
end
end
但是,当我继续尝试创建新日历时,出现以下错误:
NameError in CalendarsController#create
undefined local variable or method `current_user' for #<Calendar:0x007f88f8f26998>
Extracted source (around line #10):
def set_default_role
current_user.calendar.role = "Owner"
end
end
经过一些研究,我发现 this question on Quora 的答案如下:
It is not good practice for the model to directly have knowledge of the current user; this is an application 'state' or session related issue. The controllers should be managing the current user.
我不得不说我有点困惑:一般原则是通过将逻辑放在模型中来保持控制器瘦身。但是,上面的答案建议做相反的事情,因为模型不应该知道当前用户。
所以,回到我最初的问题:当用户创建新日历时,我如何为他定义默认角色?
我应该使用 after_create
回调,使用其他东西而不是 current_user
来获取他的 id
,还是使用完全不同的解决方案?
更新: 该模型没有 current_user。从日历模型中删除 set_default_role 并添加到管理模型:
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
before_create :set_default_role
def set_default_role
self.role = "Owner"
end
end
将此添加到 CalendarsController 创建操作:
@calendar.administrations.first.role = 'Owner'
而且我认为它会起作用。
这是我最后做的。
首先,在User
模型中,我定义了如下方法:
def set_default_role(calendar_id, role)
self.administrations.find_by(calendar_id: calendar_id).update(role: role)
end
然后,我更新了Calendars#Create
如下:
def create
@user = current_user
@calendar = @user.calendars.create(calendar_params)
respond_to do |format|
if @calendar.save
current_user.set_default_role(@calendar.id, 'Owner')
format.html { redirect_to user_calendar_path(@user,@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
现在,每当 user
创建一个新的 calendar
时,如果保存了新的 calendar
,则 current_user
默认分配给 role
所有者。