在Ruby on Rails中自动更新created_by和updated_by值

时间:2016-02-24 10:51:21

标签: ruby-on-rails ruby-on-rails-4 activerecord

我尝试自动将当前user_id添加到created_byupdated_by字段中。任何人都可以帮助我吗?

这是数据模式:

create_table "businesses", force: :cascade do |t|
  t.string "business_name"
  t.string "last_name"
  t.date "start_date"
  t.date "end_date"
  t.integer "created_by"
  t.integer "modified_by"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

3 个答案:

答案 0 :(得分:4)

首先,if-then-elseif位于您的current_user,没有任何定向方式从controller获取数据。

我想这样的解决方案,欢迎任何建议:

<强>模型

model

应用程序控制器

class User < ActiveRecord::Base
  cattr_accessor :current_user
  # Your current code
end

返回商家模型

class ApplicationController  < ActionController::Base
  before_action :set_current_user

  def set_current_user
    User.current_user = current_user if current_user
  end
end

因此,当class Business < ActiveRecord::Base # Your current code before_create :update_created_by before_update :update_modified_by def update_created_by self.created_by = current_user_id end def update_modified_by self.modified_by = current_user_id end def current_user_id User.current_user.try(:id) end end 登录并执行任何操作时,当前用户信息将设置为user,因此,如果User.current_user已创建或更新,则{{1}将通过回调设置信息。

我想在这里找到更好的解决方案,因为这不是线程安全的!

答案 1 :(得分:2)

你可能会找到一个宝石,但它总会在某些时候涉及某种手动干预。

检查ruby工具箱:Gems for user stamping

答案 2 :(得分:0)

为避免thread_safe问题,您可以在控制器中执行以下操作:

def business_params
  params.require(:object).permit(:blah, :flop, :peep).merge(updated_by: current_user.id)
end

因此,每次保存模型时,都会使用current_user的ID更新update_by字段。由于设置created_by仅发生一次(在create动作中),因此直接在此处进行设置:

@business.created_by = current_user.id

或将用户ID存储在线程中(丑陋但安全的线程):

Thread.current[:user_id] = session[:current_user.id]

古老的辩论here基本上是关于您希望在宗教上打破MVC模式并将这种逻辑纳入模型的想法。