Ruby on Rails предотвращает нулевую ошибку, когда предполагается, что запись может не существовать
-
12-09-2019 - |
Вопрос
Я создаю простое приложение для проверки книг.Одна из вещей, которые мне нужно сделать, это определить, выдана ли книга.У меня есть ассоциации между моими людьми и книжными классами через класс book_check_out.Моя цель — использовать свойство Checked_out книги, чтобы определить, извлечена ли книга в данный момент.Однако в моей нынешней реализации, когда книга не извлечена и я ссылаюсь на book.checked_out.XXX, я получаю ошибку "У вас есть нулевой объект, когда вы этого не ожидали!«Моя цель — использовать book.checked_out для двух целей: в некоторых представлениях показать, что да, эта книга извлечена, а в других представлениях показать, кому она в данный момент извлечена.
class Person < ActiveRecord::Base
has_many :book_check_outs
has_many :books, :through => :book_check_outs
end
class Book < ActiveRecord::Base
has_many :book_check_outs
has_many :people, :through => :book_check_outs
def checked_out
book_check_outs || false
end
end
class BookCheckOut < ActiveRecord::Base
belongs_to :book
belongs_to :person
end
Решение
Если у вас есть логический результат, который может быть либо истинным, либо ложным (например, книгу можно либо взять, либо нет), вам нужно принять значение по умолчанию для результата.В этом случае мы можем предположить, что это ложь (по умолчанию книга не извлечена).
В модели книги удалите has_many :checked_out строку и создайте метод с тем же именем:
def checked_out
book_check_outs || false
end
Этот должен верните либо BookCheckOuts, либо, если они не связаны с экземпляром, FALSE.Это дает вам быстрый, простой и надежный метод проверки ассоциации и устранения неприятной ошибки с нулевым объектом.
Редактировать Вы также можете просто вернуть TRUE или FALSE и не возвращать самые последние проверки, проверив, что book_check_outs равно нулю или нет.Rails предоставляет метод Blank?который называет оба нулями?и пустой?
def checked_out
!book_check_outs.blank?
end
Обожаю Руби :)
Другие советы
Я забыл, имеет ли это значение на самом деле или нет, но для ясности вы можете поместить отношение has_many выше отношения has_many :through.
Я также не уверен, что вам следует объявлять в классе Book, что он has_many :BookCheckOuts И has_one :checked_out, поскольку на самом деле - это BookCheckOut, который, как вы объявили, имеет многое из вышеперечисленного.