Rails 4, нет ошибки метода при попытке доступа к атрибутам объектов в шаблоне jbuilder

Я использую jbuilder для создания ответа json. См. ниже мой шаблон jbuilder:

json.array! @items do |item|
    json.title                          item.title
    json.description                    item.description
    json.category                       item.categories.first.title
    json.price                          item.price / 100.0
    json.status                         item.status

    if !item.banned?
        json.published_date             item.published_date
        json.seller_name                item.seller.name
    end

    json.seller_latitude        item.seller.latitude.to_f
    json.seller_longtitude      item.seller.longtitude.to_f
end

Я могу без проблем получить доступ к объекту из коллекции item.categories:

item.categories.first

Когда я пытаюсь извлечь атрибут title из возвращаемого объекта категории сверху, я получаю эту ошибку в браузере:

undefined method 'title' for nil:NilClass

Я поставил оператор byebug прямо перед этой строкой в ​​моем шаблоне jbuilder:

item.categories.first.title

И в консоли byebug я без проблем могу получить доступ к атрибуту title. См. распечатку консоли byebug ниже:

Started GET "/items.json" for ::1 at 2016-07-16 13:59:45 -0400
Processing by ItemsController#index as JSON
  Item Load (0.5ms)  SELECT "items".* FROM "items"

[1, 10] in /Users/Macbook/projects/VSC/app/views/items/index.json.jbuilder
    1: 
    2: json.array! @items do |item|
    3:  json.title                          item.title
    4:  json.description                item.description
    5:  byebug
=>  6:  json.category                       item.categories.first.title
    7:  json.price                          item.price / 100.0
    8:  json.status                         item.status
    9: 
   10:  if !item.banned?
(byebug) item.categories.first.title
  Category Load (0.3ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 1]]
"movies"
(byebug) 

Я в тупике, что я делаю не так?

РЕДАКТИРОВАТЬ:

Вот sql, который запускается, когда jbuilder отображает представление:

Started GET "/items.json" for ::1 at 2016-07-16 14:24:29 -0400
Processing by ItemsController#index as JSON
  Item Load (0.8ms)  SELECT "items".* FROM "items"
  Category Load (0.5ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 1]]
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.5ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 2]]
  CACHE (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.4ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 3]]
  CACHE (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.5ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 4]]
  CACHE (3.8ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.5ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 5]]
  CACHE (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.4ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 6]]
  CACHE (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.5ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 7]]
  CACHE (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.4ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 8]]
  CACHE (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.5ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 9]]
  CACHE (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.4ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 10]]
  CACHE (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
  Category Load (0.4ms)  SELECT  "categories".* FROM "categories" INNER JOIN "categorizations" ON "categories"."id" = "categorizations"."category_id" WHERE "categorizations"."item_id" = $1  ORDER BY "categories"."id" ASC LIMIT 1  [["item_id", 11]]
  Rendered items/index.json.jbuilder (317.5ms)
Completed 500 Internal Server Error in 329ms (ActiveRecord: 11.6ms)

ActionView::Template::Error (undefined method `title' for nil:NilClass):
    2: json.array! @items do |item|
    3:  json.title                          item.title
    4:  json.description                item.description
    5:  json.category                       item.categories.first.title
    6:  json.price                          item.price / 100.0
    7:  json.status                         item.status
    8: 
  app/views/items/index.json.jbuilder:5:in `block in _app_views_items_index_json_jbuilder___331360250519835275_70269069934300'
  app/views/items/index.json.jbuilder:2:in `_app_views_items_index_json_jbuilder___331360250519835275_70269069934300'

person malexanders    schedule 16.07.2016    source источник
comment
Хорошо, вы можете проверить SQL, который он запускает, когда Jbuilder рендерит представление? Этот SQL будет хорошей точкой отладки для начала.   -  person Arup Rakshit    schedule 16.07.2016
comment
Я отправил SQL, который запускается, когда jbuilder отображает представление, пожалуйста, посмотрите   -  person malexanders    schedule 16.07.2016
comment
Хорошо. Теперь я вижу, что есть элементы с идентификаторами от 1 до 11, которые имеют категории. Следующий элемент после id 11 нарушает код. Теперь откройте rails console и элемент, который имеет id как 12, вероятно, и я уверен, что с ним не связаны категории. И это вызывает проблему. Итак, вам нужно выполнить некоторую фильтрацию, чтобы выбрать только элементы с категориями.   -  person Arup Rakshit    schedule 16.07.2016
comment
решено! Спасибо @ArupRakshit   -  person malexanders    schedule 16.07.2016


Ответы (1)


Вы видите, что item.categories.first существует, это означает, что another_item.categories.first всегда существует, а another_item — это item в цикле:

json.array! @items do |item|
  json.category item.categories.first.title
end

Пожалуйста, проверьте это в консоли, чтобы узнать, какие элементы не имеют категории: Item.all.find_all{ |item| item.categories.empty? }

person Tan    schedule 16.07.2016