【发布时间】:2017-05-14 08:35:15
【问题描述】:
我有一个使用单表继承的类结构如下:
CashAccount > AssetAccount > FinancialAccount
相关控制器代码:
def create
@financial_account = FinancialAccount.new(financial_account_params)
respond_to do |format|
if @financial_account.save
format.html { redirect_to @financial_account, notice: 'Account was successfully created.' }
else
format.html { render :new }
end
end
end
def update
respond_to do |format|
if @financial_account.update(financial_account_params)
format.html { redirect_to @financial_account, notice: 'Account was successfully updated.' }
else
format.html { render :edit }
end
end
end
def set_financial_account
@financial_account = FinancialAccount.find_by_id(params[:id])
unless @financial_account
redirect_to root_path, :flash => { :alert => "That Account does not exist." }
return
end
end
def update_params
params.require(@financial_account.model_name.param_key)
.permit(:name, :type, :description)
end
def create_params
params.require(:financial_account)
.permit(:name, :type, :description)
end
创作作品。更新没有。没有错误。保存返回 true 但值永远不会改变。以下是在对象更新时调试状态的一些 put:
puts @financial_account.changed? //false
@financial_account.assign_attributes(financial_account_params)
puts @financial_account.changed? //true
@financial_account.description_will_change!
puts @financial_account.changed? //true
puts @financial_account.description //New Value 1
puts @financial_account.save //true
puts @financial_account.description //Old Value
puts @financial_account.update(:description => "New Value 2") //true
puts @financial_account.description //Old Value
@financial_account.description = "New Value 3"
puts @financial_account.description //New Value 3
puts @financial_account.save //true
puts @financial_account.description //Old Value
Description 是 FinancialAccount 类的简单文本属性:
create_table "financial_accounts", id: :uuid, default: "uuid_generate_v4()", force: :cascade do |t|
...
t.text "description"
...
end
部分 to_yaml 打印出@financial_account 以查看用户的储值:
delegate_hash:
name: !ruby/object:ActiveRecord::Attribute::FromUser
name: name
value_before_type_cast: Test Account
type: *1
value: Test Account
description: !ruby/object:ActiveRecord::Attribute::FromUser
name: description
value_before_type_cast: New Value 1
type: *1
value: New Value 1
数据库是PostgreSQL
更新 - DjezzzL 请求的输出
注意:这是一个多租户应用程序,所以我需要设置业务 ID
2.2.4 :001 > Business.current_id = 1
=> 1
2.2.4 :002 > tmp = FinancialAccount.first
FinancialAccount Load (0.6ms) SELECT "financial_accounts".* FROM "financial_accounts" WHERE "financial_accounts"."business_id" = $1 ORDER BY "financial_accounts"."id" ASC LIMIT 1 [["business_id", 1]]
=> #<RetainedEarningsAccount id: "0a282a84-2561-4820-8f21-b8063c1c2604", type: "RetainedEarningsAccount", name: "Owner's Retained Earnings", created_at: "2017-05-02 05:20:22", updated_at: "2017-05-02 05:20:22", description: "Old Value", business_id: 1, update_balance_flag: false, reference_number: "11", balance_cents: 0>
2.2.4 :003 > tmp.description = 'new value'
=> "new value"
2.2.4 :004 > p tmp.save
(0.2ms) BEGIN
FinancialAccount Exists (1.0ms) SELECT 1 AS one FROM "financial_accounts" WHERE ("financial_accounts"."reference_number" = '11' AND "financial_accounts"."id" != '0a282a84-2561-4820-8f21-b8063c1c2604' AND "financial_accounts"."business_id" = 1) LIMIT 1
RetainedEarningsAccount Load (0.3ms) SELECT "financial_accounts".* FROM "financial_accounts" WHERE "financial_accounts"."type" IN ('RetainedEarningsAccount') AND "financial_accounts"."id" = $1 LIMIT 1 [["id", "0a282a84-2561-4820-8f21-b8063c1c2604"]]
(0.2ms) COMMIT
true
=> true
2.2.4 :005 > p tmp.description
"Old Value"
=> "Old Value"
2.2.4 :006 > p tmp.reload.description
RetainedEarningsAccount Load (2.1ms) SELECT "financial_accounts".* FROM "financial_accounts" WHERE "financial_accounts"."type" IN ('RetainedEarningsAccount') AND "financial_accounts"."id" = $1 LIMIT 1 [["id", "0a282a84-2561-4820-8f21-b8063c1c2604"]]
"Old Value"
=> "Old Value"
注意:我的属性被标记为脏,所以不是重复的 ActiveRecord not saving after updating attribute
【问题讨论】:
-
所以你在模型中使用 before 回调?或者您的模型中包含任何日志记录或监控 gem?
-
@spickermann 没有保存或更新任何这些模型的回调。我不使用日志记录或监控 gem。
-
@scottysmalls 首先,我在您的更新操作中没有看到@financial_account 的任何设置器。你有任何 before_action 回调吗?我讲
def update; @financial_account = FinancialAccount.find(params[:id]); <try to save and others stuff to do>; end返回更新记录值。您能否提供以下执行以及相应的结果和 SQL 查询:tmp = FinancialAccount.first; tmp.description = 'new value'; p tmp.save; p tmp.description; p tmp.reload.description;? -
@DjezzzL 由于在引用financial_account 时调试没有失败,我认为可以假设但有问题的路径确实通过了 set_financial_account 方法,所以你是对的 - 我应该包括它:见上文。感谢您的彻底。我也为您在上面的查询添加了输出。
-
@scottysmalls 这是来自 tmp.save 的非常有趣的 sql 查询输出。特殊选择 id != 'id'。似乎您有一些特殊的验证。那么您能否分享您的模型定义。
标签: ruby-on-rails ruby activerecord single-table-inheritance