2015-08-25 2 views
0

Ранее я спросил question о вызовах связанных атрибутов модели.Основные методы ActiveModel, не работающие над объектами

В частности, я спросил о попытке отобразить имена экземпляров модели Vip, связанных с событием.

Изначально я был

<% @organization.events.each do |event| %> 
<p> 
    <table> 
     <tr> 
      <td> 
       <%= event.name %> 
      </td> 
      <td> 
       <%= event.vips.name %> 
      </td> 
     </tr> 
    </table> 
</p> 
<% end %> 

Что я изменил

<%= event.vips.first.name %> 

и он работал на некоторое время. В конце концов я скорректировал его до

<% event.vips.each do |vip| %> 
    <%= vip.name %> 

который также работал на некоторое время. Но когда я вернулся на компьютер после перерыва, новые формы формы событий больше не отображали имя vip на странице организации, хотя база данных обновлялась внешним ключом vip_id.

На самом деле, когда я попытался

<%= event.vips.first.name %> 

снова, я получил сообщение об ошибке сказав «неопределенный метод` имя»для ноль: NilClass»

Я действительно не знаю, что изменилось, или то, что Я поступаю неправильно. Поэтому любая помощь будет оценена по достоинству.

Update:

Чтобы прояснить эту проблему, я получаю следующие выходы из консоли:

irb(main):005:0> Event.first 
    Event Load (0.2ms) SELECT "events".* FROM "events" ORDER BY "events"."id" ASC LIMIT 1 
=> #<Event id: 1, when: "2015-08-25 00:00:00", organization_id: 1, created_at: "2015-08-25 04:47:43", updated_at: "2015-08-25 04:47:43", name: "John's Event", vip_id: 1> 

irb(main):006:0> Vip.first 
    Vip Load (0.2ms) SELECT "vips".* FROM "vips" ORDER BY "vips"."id" ASC LIMIT 1 
=> #<Vip id: 1, name: "John", created_at: "2015-08-25 04:46:23", updated_at: "2015-08-25 04:46:23", organization_id: 1, event_id: nil> 

irb(main):007:0> @organization 
=> #<Organization id: 1, name: "Test Org", created_at: "2015-08-25 04:46:03", updated_at: "2015-08-25 04:46:03", user_id: 1> 

irb(main):008:0> @organization.events.first 
=> #<Event id: 1, when: "2015-08-25 00:00:00", organization_id: 1, created_at: "2015-08-25 04:47:43", updated_at: "2015-08-25 04:47:43", name: "John's Event", vip_id: 1> 

irb(main):009:0> @organization.events.first.vips 
    Vip Load (0.2ms) SELECT "vips".* FROM "vips" WHERE "vips"."event_id" = ? [["event_id", 1]] 
=> #<ActiveRecord::Associations::CollectionProxy []> 
irb(main):010:0> 
+1

Привет Райан. Можете ли вы отобразить 'Event'' vips' с '<% = event.vips.inspect%>'? Что он возвращает? –

+0

Это означает, что 'event.vips.first' является' nil' и, следовательно, является ошибкой. «Vips» против определенного «события» удаляются. – usmanali

+0

@ Yanis Vieilly Да, это пример блока, который проходит один раз «Событие Джона \t # ", когда я использую '<% = event.vips.inspect%>' –

ответ

0

Ваш event не указал vips. Поскольку event.vips в основном пустой массив, вызывающий #first на нем возвращает nil. Затем вы пытаетесь позвонить #name по телефону nil. Но #name не является методом nil, следовательно, ошибка undefined method 'name' for nil:NilClass.

+0

Так что это часть причины, по которой я запутался. Если я перейду к консоли и наберу «Event.first», я получу «=> # <Идентификатор события: 1, когда:« 2015-08-25 00:00:00 », organization_id: 1, created_at:" 2015-08-25 04:47:43 », updated_at:« 2015-08-25 04:47:43 », имя:« Событие Джона », ** vip_id: 1 **>», и когда я печатаю 'Vip .first 'I get "=> # " –

+1

Если в '' '' '' 'много' Vip', в таблице событий 'events' не должно быть' vip_id'. Я настоятельно рекомендую вам прочитать это руководство Rails, которое объясняет это подробно: http://guides.rubyonrails.org/association_basics.html –

-1

Ваш код будет работать, если обновить event_id вип

Vip.first.update_attribute event_id, Event.first.id 

Проблема произойдет, потому что у нас нет связи между Event.first и Vip.first

Кстати, я не думаю, мы должны использовать event.vips.first.name потому VIPs может быть пустым мы можем изменить его немного, например:

event.vips.first.try(:name) 

или

event.vips.map(&:name).join(", ") 
0

Обычно

  1. event.vips.first.name возвращает ошибку, если вы получили event.vips.first это Nil (который просто означает, что это конкретное событие не имеет VIPs, потому что .first вернулся Nil или ничего) ,

  2. В некоторых других случаях, однако, event.vips.first является записью Vip (что означает, что это конкретное событие имеет хотя бы один Vip).

Поскольку в моем первом сценарии он вернулся nil, то nil.name, очевидно, возвращает ошибку. Однако в моем втором сценарии, который он перенастроил vip, тогда vip.name теперь будет работать так, как вы ожидали.

Вы можете попробовать это, если вы хотите, чтобы игнорировать ошибку воспитываются: event.vips.first.try(:name)