问题更新:我正在尝试在编辑购买时保存当前用户的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
答案 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_one
或has_many
的关系。
我建议您为此创建一个不同的模型,因为它更容易维护,而您尝试实现的方法违反了single responsibility principle。 Marked模型将具有两个模型的外键,因为它对于两个模型都具有关系belongs_to。请看一下belongs to association。