Rails attr_accessible не работает для: типа? - PullRequest
4 голосов
/ 21 октября 2009

Я пытаюсь установить тип модели наследования одной таблицы в форме. Так что у меня есть меню выбора для атрибута: тип и значения являются именами подклассов STI. Проблема в том, что журнал ошибок продолжает печатать:

ВНИМАНИЕ: Не удается назначить массово эти защищенные атрибуты: тип

Итак, я добавил «attr_accessible: type» к модели:

class ContentItem < ActiveRecord::Base
  # needed so we can set/update :type in mass
  attr_accessible :position, :description, :type, :url, :youtube_id, :start_time, :end_time
  validates_presence_of :position
  belongs_to :chapter
  has_many :user_content_items
end

Ничего не меняет, ContentItem по-прежнему имеет: type = nil после вызова в контроллере .update_attributes (). Любая идея, как массово обновить: тип из формы?

Ответы [ 5 ]

20 голосов
/ 17 ноября 2010

мы можем переопределить attribute_protected_by_default

class Example < ActiveRecord::Base

  def self.attributes_protected_by_default
    # default is ["id","type"]
    ["id"]
  end
end

e = Example.new(:type=>"my_type")
9 голосов
/ 21 октября 2009

Вы должны использовать правильный конструктор, основанный на подклассе, который вы хотите создать, вместо вызова конструктора суперкласса и назначения типа вручную. Пусть ActiveRecord сделает это за вас:

# in controller
def create
   # assuming your select has a name of 'content_item_type'
   params[:content_item_type].constantize.new(params[:content_item])
end

Это дает вам преимущества определения различного поведения в ваших подклассах метод initialize () или обратные вызовы. Если вам не нужны эти виды преимуществ или вы планируете часто менять класс объекта, вы можете пересмотреть использование наследования и просто придерживаться атрибута.

6 голосов
/ 21 октября 2009

Дуплекс на railsforum.com нашел обходной путь:

использовать виртуальный атрибут в формах и в модели вместо типа dirtectly:

def type_helper   
  self.type 
end 
def type_helper=(type)   
  self.type = type
end

работал как шарм.

4 голосов
/ 21 октября 2009

"type" иногда вызывает проблемы ... Я обычно использую "kind" вместо этого.

Смотри также: http://wiki.rubyonrails.org/rails/pages/ReservedWords

1 голос
/ 20 августа 2010

Я следовал http://coderrr.wordpress.com/2008/04/22/building-the-right-class-with-sti-in-rails/ за решение той же проблемы, что и я. Я довольно новичок в мире Rails, поэтому не уверен, хорош ли этот подход или нет, но он работает очень хорошо. Я скопировал код ниже.

class GenericClass < ActiveRecord::Base
  class << self
    def new_with_cast(*a, &b)
      if (h = a.first).is_a? Hash and (type = h[:type] || h['type']) and (klass = type.constantize) != self
      raise "wtF hax!!"  unless klass < self  # klass should be a descendant of us
      return klass.new(*a, &b)
    end
    new_without_cast(*a, &b)
  end
  alias_method_chain :new, :cast
end

class X < GenericClass; end
GenericClass.new(:type => 'X') # => #<X:0xb79e89d4 @attrs={:type=>"X"}>
...