Rails 3 - "неопределенный метод" ноль? "для nil: NilClass "во многих отношениях многие - PullRequest
0 голосов
/ 17 января 2012

У меня проблема с отношением «многие ко многим» в Rails 3. Здесь задействованы 3 модели:

class Device < ActiveRecord::Base
  attr_accessible :name, :protocol, :address, :status, :room_id

  belongs_to :room

  has_many :device_abilities
  has_many :abilities, :through => :device_abilities
end

class Ability < ActiveRecord::Base
  attr_accessible :name

  has_many :device_abilities
  has_many :devices, :through => :device_abilities
end

class DeviceAbility < ActiveRecord::Base

  belongs_to :device
  belongs_to :ability
end

, и у меня есть следующее в моем начальном файле для тестирования:

device_abilities = DeviceAbility.create([
  { device_id: '1', ability_id: '1'},
  { device_id: '1', ability_id: '2'},
  { device_id: '1', ability_id: '3'},
  { device_id: '1', ability_id: '4'},
  { device_id: '1', ability_id: '5'},
  { device_id: '2', ability_id: '1'},
  { device_id: '2', ability_id: '2'},
  { device_id: '2', ability_id: '3'},
  { device_id: '2', ability_id: '4'},
  { device_id: '2', ability_id: '5'}
  ])

(реальные устройства и способности также определены, и я могу нормально с ними взаимодействовать).

Я получаю необычную ошибку при попытке сделать

def show
  @device = Device.find(params[:id])
  puts @device.abilities
end

(put - для отладки; я также не могу использовать это, если помещаю это в переменную).Ошибка:

undefined method `zero?' for nil:NilClass

Может кто-нибудь сказать мне, где я иду не так?

обновление:

по запросу, трассировка ошибки:

app/controllers/devices_controller.rb:13:in `puts'
app/controllers/devices_controller.rb:13:in `puts'
app/controllers/devices_controller.rb:13:in `show'

и схема:

create_table "abilities", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
end

create_table "devices", :force => true do |t|
    t.string   "name"
    t.string   "protocol"
    t.string   "address"
    t.boolean  "status"
    t.integer  "room_id"
    t.datetime "created_at"
    t.datetime "updated_at"
end

create_table "device_abilities", :force => true do |t|
    t.integer  "device_id"
    t.integer  "ability_id"
    t.datetime "created_at"
    t.datetime "updated_at"
end

Ответы [ 3 ]

2 голосов
/ 02 октября 2012

Ответили здесь: Rails 3.2 Проверка уникальности вызывает неопределенный метод 'zero?' для ноля: нилькласс

Ваш sum метод добавляется в Array и переопределяет собственный Rails Enumerable#sum.

Как это исправить?

Вы написали метод с именем sum, возможно, внутри модуля с именем Перечислимый или Массив? Если так, то это хорошее место для начала. Вы могли бы переименуйте ваш метод, или вы можете попробовать изменить метод, чтобы он соответствовал Метод Rails, заменив код #sum следующим кодом:

модуль Перечислимая сумма суммы (идентификатор = 0, & блок) если block_given? Карта (& блок) .sum (идентичность) еще ввести (: +) || идентичность конец конец конец (опять же: взять из Rails 3.2 Проверка уникальности вызывает неопределенный метод 'zero?' для nil: Nilclass )

1 голос
/ 18 января 2012

ОК, мне наконец удалось сузить это до фрагмента кода, который я поместил в свой файл environment.rb:

class Array
  def sum
      self.inject{|sum,x| sum + x }
  end
end

Это сделано для того, чтобы я мог сделать array.sum и получить ответ, который хорошо работал до сих пор. Я был бы очень признателен за любые комментарии относительно того, почему это вызывает такую ​​проблему, и есть ли способ обойти это, так как другие разделы моего кода полагаются на этот метод.

Спасибо!

0 голосов
/ 17 января 2012

Возможно, проблема в том, что вы не используете :dependent => :destroy Поведение по умолчанию - установить foreign_key на nil. Так что если у вас есть объект DeviceAbility и вы связываете объект Device и объект Ability, это нормально, но когда вы удаляете один из них, вы больше не можете работать с ним, потому что удаленный объект равен nil. И nil не имеет метода с именем zero?. Вы могли бы посчитать, что используя этот запрос:

DeviceAbility.where("device_id IS NULL OR ability_id IS NULL")

Если это даст какие-либо результаты, тогда вы знаете, в чем причина проблемы!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...