Rails before_update,before_save 对 Devise 的 user 奇怪的行为

stc · 2012年06月18日 · 最后由 stc 回复于 2012年06月19日 · 4502 次阅读

我有 users,roles,roles_users 三张表用来做角色的,在页面编辑 user 时 roles 字段是 select 形式保存 roles id 的,我想在保存 user 前对 role 进行转换然后保存,但非常奇怪的是触发不了 before_save 或者 before_update,更奇怪的是 logout 的时候 before_save 竟然被触发了,请求帮助!

class User < ActiveRecord::Base
  before_save :setup_roles
  before_update :setup_roles

  def setup_roles
    roles = roles.select{|r| r!=""}.collect{|r| Role.find(r)}
  end

  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :roles_users
  has_many :roles, :through => :roles_users
end

logout 的时候,devise 缺省会更新最后登录的时间,所以会触发 before_save.

这里我给的建议是,直接在 controller 里完成转换,而不是在 callback 里。callback 只应该进行表关联或缺省值设定。

#1 楼 @lyfi2003 恩,logout 是这么回事,其他的很奇怪...谢谢你的建议,我现在先放在 controller 里转换了..

不要同时用 before_save 和 before_update 哎,会执行两次的

#3 楼 @ywencn 悲剧的地方是这里一次也没执行...

before_save 可以由 save and update触发。before_update 只有 update会触发。

信息太少 不知道为啥不会触发。如果你不是为了练手,你可以选择用 cancan这个 GEM 配合 DEVICE。

... 应该是触发了 但是你这写的不对 roles = roles.select{|r| r!=""}.collect{|r| Role.new(r)} 应该是 self.roles = roles.select{|r| r!=""}.collect{|r| Role.new(r)}

#6 楼 @raven 这里我曾设置了 debugger,没有进来. 另外这里 self.roles 和 roles 有什么区别吗,我直觉觉得应该都是对当前的实例引用呵呵,烦请普及..

能说说 setup_roles 是个什么意思不?

#8 楼 @ywencn 是想为了转换页面表单传过来的 roles ids 成 Role 对象,通过 ActiveRecord 的关系来保存到 RolesUsers 表

<%= simple_form_for @user do |f| %>
    <%= f.input :email %>
    <%= f.input :password %>
    <%= f.input :roles,:collection => Role.get_all_id_name,
        :input_html=>{:multiple => true} %>
    <%= f.button :submit %>
<% end %>
需要 登录 后方可回复, 如果你还没有账号请 注册新账号