在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
。
答案 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')
)