Есть две разные проблемы:
1) Почему не работает версия с byebug
Это важная часть из документов find
: Возвращает первое, для которого блок не является ложным.
Теперь давайте посмотрим на ваши случаи:
# just writing "true" here, with no if statement will deliver a result
Если вы просто напишите true
в конце блоказатем возвращается true
и, следовательно, find
находит эту запись.
if (event.end_time > instance.start_time && event.end_time <= instance_end_time && instance.events.first.period == event.period)
ok = true
end
ok
Этот случай аналогичен: если условие if
равно true
, вы присваиваете true
ok
переменная.Поскольку вы снова вызываете ok
в последней строке блока, блок возвращает true
и find
находит этот элемент.
if (event.end_time > instance.start_time && event.end_time <= instance_end_time && instance.events.first.period == event.period)
byebug
end
Но этот пример в вашем коде отличается.Здесь вы открываете bundle
, если условие if
равно true
.Это заставляет bundler
вызывать последний вызов метода в блоке find
.Вызов bundler
не возвращает true
, поэтому весь блок не возвращает true
, а find
не выбирает эти записи.
Решение состоит в том, чтобы вернуть true
в последнемлиния блока find
.Поскольку в вашем коде уже есть условие, вы можете использовать его напрямую, не назначая сначала true
переменной.- например, вот так:
cspg_instance = @game_instances.find do |instance|
instance_end_time = TimeOperation.new(:+, instance.start_time, instance.duration).result
event.end_time > instance.start_time && event.end_time <= instance_end_time && instance.events.first.period == event.period
end
2) Почему find_all
и select
работают, а find
нет?
В комментариях вы уточнили, что @game_instances
на самом деле это не массив, а ActiveRecord::Relation
.ActiveRecord::Relation#find
работает совершенно иначе, чем метод на Array
.Упрощенный find
для такого отношения ожидает id
записи и возвращает эту запись в объеме, заданном отношением.Вызов to_a
для отношения загружает все записи в память и позволяет использовать Array#find
.
С точки зрения производительности имеет смысл перевести условие в условие SQL и загрузить только однозапись, совпадающая с базой данных, вместо загрузки всех записей и поиска нужной в вашем приложении.