Ruby / Datamapper 创建或更新问题 - 不可变错误

发布于 2024-10-27 09:54:15 字数 1774 浏览 1 评论 0原文

我有一个用户类别,可以选择有一个帐单地址。当我发布付款表单时,假设用户已表示他们想要保存其帐单地址详细信息,我想要创建一个新的地址记录或更新原始地址记录。

我已经尝试了很多事情,但我能得到的最接近工作代码是......

class User
  include DataMapper::Resource
  property :id,          Serial
  property :provider,    String, :length => 100
  property :identifier,  String, :length => 100
  property :username,    String, :length => 100
  property :remember_billing, Boolean
  has 1, :billing_address
end

class BillingAddress
  include DataMapper::Resource
  property :first,       String, :length => 20
  property :surname,     String, :length => 20
  property :address1,    String, :length => 50
  property :address2,    String, :length => 50
  property :towncity,    String, :length => 40
  property :state,       String, :length => 2
  property :postcode,    String, :length => 20
  property :country,     String, :length => 2
  property :deleted_at,  ParanoidDateTime
  belongs_to :user, :key => true
end

post "/pay" do
  @post = params[:post]
  @addr = params[:addr]
  if @addr == nil
    @addr = Hash.new
  end

  user = User.first(:identifier => session["vya.user"])
  user.remember_billing = !!@post["remember"]

  if user.remember_billing
    user.billing_address = BillingAddress.first_or_create({ :user => user }, @addr)
  end
  user.save
  ...

在没有记录的情况下工作正常。但如果已经有记录,它会保留原始值。

我看到过类似的帖子 DataMapper:创建新记录或更新现有记录 但如果我将代码更改为

user.billing_address = BillingAddress.first_or_create(:user => user).update(@addr)

我会收到错误

DataMapper::ImmutableError at /pay
Immutable resource cannot be modified

任何帮助非常感谢

I'm have a user class that can optionally have a billing address. When I post a payment form, assuming the user has indicated they want to save their billing address details, I want to either create a new address record or update the original one.

I have tried many things but the closest I can get to working code is...

class User
  include DataMapper::Resource
  property :id,          Serial
  property :provider,    String, :length => 100
  property :identifier,  String, :length => 100
  property :username,    String, :length => 100
  property :remember_billing, Boolean
  has 1, :billing_address
end

class BillingAddress
  include DataMapper::Resource
  property :first,       String, :length => 20
  property :surname,     String, :length => 20
  property :address1,    String, :length => 50
  property :address2,    String, :length => 50
  property :towncity,    String, :length => 40
  property :state,       String, :length => 2
  property :postcode,    String, :length => 20
  property :country,     String, :length => 2
  property :deleted_at,  ParanoidDateTime
  belongs_to :user, :key => true
end

post "/pay" do
  @post = params[:post]
  @addr = params[:addr]
  if @addr == nil
    @addr = Hash.new
  end

  user = User.first(:identifier => session["vya.user"])
  user.remember_billing = !!@post["remember"]

  if user.remember_billing
    user.billing_address = BillingAddress.first_or_create({ :user => user }, @addr)
  end
  user.save
  ...

which works fine when there is no record. But if there is already a record, it keeps the original values.

I saw a similar post
DataMapper: Create new record or update existing
but if I alter the code to be

user.billing_address = BillingAddress.first_or_create(:user => user).update(@addr)

I get the error

DataMapper::ImmutableError at /pay
Immutable resource cannot be modified

Any help much appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

简美 2024-11-03 09:54:15

你把很多东西链接在一起。怎么样:

billing = BillingAddress.first_or_new(:user => user, @addr) #don't update, send the hash as second parameter
billing.saved? ? billing.update(@addr) : billing.save
raise "Billing is not saved for some reason: #{billing.errors.inspect}" unless billing && billing.saved?
user.billing_address = billing
user.save

You're chaining lots of things together, there. How about:

billing = BillingAddress.first_or_new(:user => user, @addr) #don't update, send the hash as second parameter
billing.saved? ? billing.update(@addr) : billing.save
raise "Billing is not saved for some reason: #{billing.errors.inspect}" unless billing && billing.saved?
user.billing_address = billing
user.save
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文