Модель Rails - attr_accessor вызывает исключение неизвестного метода?

Краткая версия (фиктивный код):

Итак, у меня есть один класс ActiveRecord (модель rails):

class User < ActiveRecord::Base
    attr_accessor :somevar
end

Когда я делаю

@u=User.find(1)
@u.somevar = 1

я получил

undefined method `somevar=' for #<Class:0x007fa8cd0016a8>

У меня нет в базе данных столбца с именем somevar
Я перезапустил rails server после добавления attr_accessor (на всякий случай)
Все еще получаю чертову ошибку.
много погуглил!

Где может быть ошибка? Есть предположения?

Я ценю все ответы! Спасибо!


Длинная версия (с актуальным кодом)

Я использую Devise для управления своими пользователями. Также я пытаюсь добавить условие по умолчанию для фильтрации результатов на некоторых моделях. Это основано на «company_id», который находится в модели пользователя. Я попытался использовать переменную сеанса в default_scope и нашел это. По сути, это говорит о том, что использовать переменные сеанса для условий по умолчанию — плохая практика, и я мог бы использовать Devise и добавить некоторые модификации.

Это привело к тому, что мой User model стал

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  attr_accessor :current_company

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  belongs_to :company
end

И мой ApplicationController

class ApplicationController < ActionController::Base
  around_filter :scope_current_user  

  def scope_current_user
        User.current_company = current_user.company_id
    yield
    ensure
        #avoids issues when an exception is raised, to clear the current_id
        User.current_company = nil       
  end
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead. 
  protect_from_forgery with: :exception

end

Затем он поднимается от ApplicationController

undefined method `current_company=' for #<Class:0x007fa8cd0016a8>

То же самое произойдет, если я определяю методы вручную:

def current_company
    @current_company
end
def current_company=(new_val)
    @current_company = new_val
end

person Andreas Storvik Strauman    schedule 03.06.2014    source источник
comment
Вы уверены, что @u=User.find(1) возвращает ожидаемый результат?   -  person Tamer Shlash    schedule 03.06.2014
comment
Я думаю, что большая проблема заключается в том, что я на самом деле не понимаю, что происходит с измененным кодом в файле ApplicationController. Я обновил свой вопрос и включил фактический исходный код.   -  person Andreas Storvik Strauman    schedule 03.06.2014


Ответы (1)


Это неправильно:

User.current_company = current_user.company_id

Строка attr_accessor :current_company добавляет атрибут к экземплярам пользователя, а не к классу пользователя. Вы можете использовать аксессор current_company как:

current_user.current_company = # whatever

В этом URL вам не хватает того, что он фактически использует cattr_accessible а не attr_accessor. Итак, ваша модель должна быть установлена:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  cattr_accessible :current_company

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  belongs_to :company
end

Это должно работать.

ОБНОВЛЕНИЕ НА ОСНОВЕ ПОСЛЕДНЕГО ИЗМЕНЕНИЯ:

Даже когда вы определяете методы вручную, вы совершаете ту же ошибку: вы определяете методы экземпляра и пытаетесь вызвать их как методы класса. Вы должны определить их как методы класса, что делается путем добавления self. перед именами методов, например:

def self.current_company
    @@current_company
end
def self.current_company=(new_val)
    @@current_company = new_val
end

Пожалуйста, скажите мне, если это не работает.

person Tamer Shlash    schedule 03.06.2014
comment
До'х. Конечно. Тем не менее, когда я использую cattr_accessible, я получаю undefined method cattr_accessible :( - person Andreas Storvik Strauman; 03.06.2014
comment
Таким образом, литерал, который вы добавили последним, работает. Однако cattr_accessible вызывает исключение. Есть идеи, почему? В любом случае, спасибо! - person Andreas Storvik Strauman; 03.06.2014
comment
@AndreasStorvikStrauman попробуйте вместо этого cattr_accessor. Тем не менее, вам лучше придерживаться определенных вручную методов, таких как link говорит, что это потокобезопасный. - person Tamer Shlash; 03.06.2014