有条件地包含属性是create方法--Rails 5

时间:2018-05-21 16:10:22

标签: ruby-on-rails ruby ruby-on-rails-5

create(或任何method(attr, attr, attr)样式方法中)有条件地包含属性的最佳方法是什么?

@user = User.find_by_name("Sam") # <- might not exist

Store.create(
  name: "Some Store",
  email: "store@example.com",
  user_id: @user.id if @user.present? # <- CONCEPT ONLY - Should be added if condition is true to prevent error
)
如果user_id: @user.id未找到,则@user行会引发错误,因此nil

2 个答案:

答案 0 :(得分:2)

您忘记了.create()的参数是哈希的快捷方式。使哈希显式:

hash = {
  name: "Some Store",
  email: "store@example.com"
} 
hash[:user_id] = @user.id if @user.present?
Store.create(hash)

另一个选择是传递.create一个块:

Store.create do |s|
  s.name = "Some Store"
  s.email = "store@example.com"
  s.user_id = @user.id if @user
end

答案 1 :(得分:2)

我可以使代码工作的最小变化是:

Store.create(
  name: "Some Store",
  email: "store@example.com",
  user_id: @user&.id
)

这是使用安全导航操作符(&.)来“忽略nil值上的方法调用”。

但是,为什么要获取一个可能为零的对象,然后尝试在其上调用方法?根据您原始帖子的背景,您可以改为:

Store.create(
  name: "Some Store",
  email: "store@example.com",
  user: @user
)

无论@user是否存在,这都可以正常工作。

......或者甚至,你真正打算做的事情是:

Store.create(
  name: "Some Store",
  email: "store@example.com",
  user: User.find_or_create_by(name: 'Sam')
)
相关问题