Ruby-on-rails Rails 可选的belongs_to

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16699877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:02:00  来源:igfitidea点击:

Rails optional belongs_to

ruby-on-railsrubyactiverecord

提问by tsm

I'm writing a Rails frontend for inventory management. I want users to be able to register products, so I have:

我正在编写一个用于库存管理的 Rails 前端。我希望用户能够注册产品,所以我有:

class User < ActiveRecord::Base
  has_many :products
  # <snip>
end

and

class Product < ActiveRecord::Base
  belongs_to :user
  # <snip>
end

The problem is that products are created prior to being registered by a user. That is, it's perfectly acceptable to call Product.createand just have it set the user_idto nil. As you can imagine, though, Rails doesn't support this out of the box:

问题是产品是在用户注册之前创建的。也就是说,这是完全可以接受的呼吁Product.create,只是把它设置user_idnil。但是,正如您可以想象的那样,Rails 并不支持这种开箱即用的功能:

> Product.create!
   (0.3ms)  SELECT COUNT(*) FROM "products" WHERE "products"."type" IN ('Product')
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
ActiveRecord::RecordInvalid: Validation failed: User can't be blank
    from ~/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/validations.rb:56:in `save!'

I've thought about a bunch of kludgey workarounds, the most appealing of which is to have a NullUsersubclassing Userand use that to create products. But that still seems like a hack. What's the Rails Way with this?

我想过一堆笨拙的解决方法,其中最吸引人的是创建NullUser子类User并使用它来创建产品。但这似乎仍然是一个黑客。这个 Rails 方式是什么?

Thanks.

谢谢。



The relevant migration:

相关迁移:

class AddUseridToProducts < ActiveRecord::Migration
  def change
    add_column :products, :user_id, :integer
  end
end

and later:

然后:

class Changeuseridtobeoptionalforproducts < ActiveRecord::Migration
  def change
    change_column :products, :user_id, :integer, null: true
  end
end

采纳答案by Matt

Do you have a validation that requires user be present? If so, remove that.

您是否有需要用户在场的验证?如果是这样,请删除它。

回答by Alexis

Just an update for rails 5, if you want this kind of behavior you will need to pass this option:

只是 Rails 5 的更新,如果你想要这种行为,你需要传递这个选项:

belongs_to :user, optional: true

In Rails 5, whenever we define a belongs_to association, it is required to have the associated record present by default.

在Rails 5 中,每当我们定义一个belongs_to 关联时,默认情况下都需要存在关联的记录。

Update
If you still want to use the old behavior by default you can add the configuration to your application.rb file.

更新
如果您仍然希望默认使用旧行为,您可以将配置添加到您的 application.rb 文件中。

# /config/application.rb
config.active_record.belongs_to_required_by_default = false

notice:there were some issueson early releases of Rails 5 with this configuration, but is currently fixed, tested on the release candidate 5.2.3.

注意:使用此配置的 Rails 5 的早期版本存在一些问题,但目前已修复,并在候选版本5.2.3上进行了测试。

回答by Matt

Rails absolutely supports this out of the box, check your migrate, have you included a constraint such as :null => falseon the user_idline? If so, take it out!

Rails的绝对支持这个开箱,检查你的迁移,有你提供一个约束,例如:null => falseuser_id线?如果有,就拿出来!

Edit: Or as @Rodrigo Dias states, reverse it to :null => true.

编辑:或者如@Rodrigo Dias 所述,将其反转为:null => true.

Also, check that you don't have any validations on the user relation in the Product model.

此外,请检查您是否对 Product 模型中的用户关系没有任何验证。