Rails 4 has_many:通过关联:在其他父模型after_create回调中使用Devise current_user

时间:2015-08-28 14:44:18

标签: ruby-on-rails ruby-on-rails-4 devise callback has-many-through

我有三个模型,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分配“所有者” ”

我认为最好的方法是在after_create模型中使用calendar回调,如下所示:

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的答案如下:

  

模型直接掌握知识并不是一种好的做法   当前用户;这是一个应用程序“状态”或会话相关   问题。控制器应该管理当前用户。

我不得不说我有些困惑:一般原则是通过将逻辑放在模型中来保持控制器的瘦。但是,上面的答案暗示要做相反的事情,因为模型不应该知道当前的用户。

那么,回到我的初步问题:如何在用户创建新日历时为其定义默认角色?

我应该使用after_create回调,使用其他内容而不是current_user来获取id,还是使用完全不同的解决方案?

3 个答案:

答案 0 :(得分:0)

<强>更新 该模型没有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

答案 1 :(得分:0)

将此添加到CalendarsController创建操作:

@calendar.administrations.first.role = 'Owner'

我觉得它会起作用。

答案 2 :(得分:0)

这是我最终做的事情。

首先,在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所有者。