编辑购买时如何将当前用户保存到数据库?

时间:2016-08-04 16:35:46

标签: ruby-on-rails

问题更新:我正在尝试在编辑购买时保存当前用户的ID。特别是当购买被标记为已收到时。

我有一个before_update回调函数,该方法在购买被标记为已收到时保存日期时间,这很有效,我只需要弄清楚如何将购买编辑器的id传递给数据库。

在user.rb

class User < ActiveRecord::Base

  has_many :purchase_edits, :foreign_key => :purchase_editor_id
  has_many :edited_purchases, :through => :purchase_edits
  has_many :created_purchases, :foreign_key => :creator_id, :class_name => "Purchase"
end

在purchase.rb

class Purchase < ActiveRecord::Base
  belongs_to :vendor
  belongs_to :creator, :class_name => "User"
  has_many :purchase_edits, :foreign_key => :edited_purchase_id
  has_many :editors, :through => :purchase_edits, :source => :purchase_editor

  before_update :update_marked_received_date

  ## Saves date when marked received. ##
  def update_marked_received_date
    return unless received == true
    self.marked_received = Time.now
  end
end

在purchase_edit.rb(加入表格)

class PurchaseEdit < ActiveRecord::Base
  belongs_to :purchase_editor, :class_name => "User"
  belongs_to :edited_purchase, :class_name => "Purchase"
end

在purchases_controller.rb,(创建和更新)中,我有:

  def create
    @vendor_options = Vendor.order("name ASC").all.map{ |u| [ u.name, u.id ] }
    @purchase = Purchase.new(purchase_params)
    @purchase.creator = current_user
    if @purchase.save
      redirect_to @purchase
    else
      render 'new'
    end
  end

  def update
    @vendor = Vendor.all
    @vendor_options = Vendor.order("name ASC").all.map{ |u| [ u.name, u.id ] }
    @purchase = Purchase.find(params[:id])
    if @purchase.update(purchase_params)
      flash[:notice] = 'Update successful.'
      redirect_to @purchase
    else
      render 'edit'
    end
  end

在Schema.rb中

  create_table "purchases", force: :cascade do |t|
    t.integer  "vendor_id"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "order_number"
    t.string   "tradegecko_url"
    t.integer  "creator_id"
    t.boolean  "received",            default: false, null: false
    t.date     "estimated_ship_date"
    t.boolean  "closed",              default: false, null: false
    t.datetime "marked_received"
  end

  create_table "purchase_edits", id: false, force: :cascade do |t|
    t.integer "purchase_editor_id", null: false
    t.integer "edited_purchase_id", null: false
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "",    null: false
    t.string   "encrypted_password",     default: "",    null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,     null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.datetime "created_at",                             null: false
    t.datetime "updated_at",                             null: false
    t.boolean  "admin",                  default: false
  end

2 个答案:

答案 0 :(得分:1)

对于遇到这个问题的任何人(以及我未来的自我),我就是这样做的:

首先,在application_controller.rb中:

class ApplicationController < ActionController::Base

  before_action :set_current_user

  def set_current_user
    User.current = current_user
  end
end

然后在user.rb中:

class User < ActiveRecord::Base

  has_many :created_purchases, class_name: 'Purchase', foreign_key: 'creator_id'
  has_many :received_purchases, class_name: 'Purchase', foreign_key: 'receiver_id'

  def self.current
    Thread.current[:user]
  end
  def self.current=(user)
    Thread.current[:user] = user
  end

  def purchases
    Purchase.where("creator_id = ? OR receiver_id = ?", self.id, self.id)
  end
end

最后,在purchase.rb:

class Purchase < ActiveRecord::Base

  belongs_to :creator, class_name: "User", foreign_key: "creator_id"
  belongs_to :receiver, class_name: "User", foreign_key: "receiver_id"

  before_update :update_marked_received

  def update_marked_received
    return unless received == true
    if self.marked_received.blank?
      self.marked_received = Time.now
      self.receiver_id = User.current.id
    end
  end
end

现在,当购买标记为已收到时,会记录时间戳和用户。

答案 1 :(得分:0)

Class Purchase
  belongs_to :created_by, class_name: 'User', foreign_key: 'created_by_id'
  has_one :marked
end

Class Marked
  belongs_to :purchase
  belongs_to :user
end

这可能对你有利。此外,您可以根据您的要求保持标记has_onehas_many的关系。

我建议您为此创建一个不同的模型,因为它更容易维护,而您尝试实现的方法违反了single responsibility principle。 Marked模型将具有两个模型的外键,因为它对于两个模型都具有关系belongs_to。请看一下belongs to association