如果找不到对象,则创建一个对象

时间:2014-08-14 18:13:43

标签: ruby ruby-on-rails-4

如果找不到对象,如何创建对象?这是我正在运行的查询:

  @event_object = @event_entry.event_objects.find_all_by_plantype('dog')

我正在尝试这个:

  @event_object = EventObject.new unless @event_entry.event_objects.find_all_by_plantype('dog')

但这似乎不起作用。我知道我错过了一些非常简单的东西:(感谢您的帮助!!! :)

2 个答案:

答案 0 :(得分:3)

find_all样式方法返回一组匹配的记录。如果找不到匹配的记录,那么这是一个空数组。一个空的是 truthy 。这意味着:

arr = []
if arr
  puts 'arr is considered turthy!' # this line will execute
end

此外,动态查找程序方法(如find_by_whatever)为officially depreacted所以你不应该使用它们。

你可能想要更像的东西:

@event_object = @event_entry.event_objects.where(plantype: 'dog').first || EventObject.new

但您也可以更好地配置事件对象,因为您显然希望它属于@event_entry

@event_object = @event_entry.event_objects.where(plantype: 'dog').first
@event_object ||= @event_entry.event_objects.build(plantype: dog)

在最后一个示例中,我们尝试通过获取匹配记录数组并询问第一个项目来查找现有对象。如果没有商品,@event_object将为nil

然后我们使用||=运算符表示“如果当前设置为假值,则指定右侧的值”。 nil是假的。因此,如果它是nil,我们可以构建它应该属于的关联对象。我们可以预设它的属性。

答案 1 :(得分:2)

为什么不使用内置查询方法,例如find_or_create_byfind_or_initialize_by

@event_object = @event_entry.event_objects.find_or_create_by(plantype:'dog')

如果一个@event_entry.event_object不存在,我会找到plantype = 'dog',然后会创建一个。{/ p>

find_or_initialize_by可能更符合您的要求,因为它会使@event_object处于未保存的状态,只有关联和plantype设置

@event_object = @event_entry.event_objects.find_or_initialize_by(plantype:'dog')

这假设您正在寻找单个event_object,因为它会返回找到的第一个plantype = 'dog'。如果event_object范围内的plantype ='dog'多于@event_entry,那么这可能不是最佳解决方案,但它似乎符合您的描述。