Pergunta

Estou tentando definir a herança única tabela de tipo de modelo em um formulário. Então, eu tenho um menu de seleção para o atributo: tipo e os valores são os nomes das subclasses STI. O problema é o log de erro mantém a impressão:

AVISO: Não é possível massa atribuir esses atributos protegidos: tipo

Então eu adicionei "attr_accessible: tipo" para o modelo:

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

não muda nada, a ContentItem ainda tem: type = nulo após .update_attributes () é chamado no controlador. Alguma idéia de como atualização em massa a:? Tipo de um formulário

Foi útil?

Solução 3

Duplex em railsforum.com encontrada uma solução alternativa:

usar um atributo virtual nas formas e no modelo em vez do tipo dirtectly:

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

Trabalhou como um encanto.

Outras dicas

podemos substituir attributes_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")

Você deve usar o construtor adequada com base na subclasse você deseja criar, em vez de chamar o construtor da superclasse e atribuindo tipo manualmente. Let ActiveRecord fazer isso para você:

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

Isto dá-lhe os benefícios da definição de um comportamento diferente em suas subclasses initialize método ou retornos de chamada (). Se você não precisar destes tipos de benefícios ou estão planejando para alterar a classe de um objeto com freqüência, você pode querer reconsiderar o uso de herança e ficar com um atributo.

"tipo" às vezes causa problemas ... Eu costumo usar "tipo" em vez.

Veja também: http://wiki.rubyonrails.org/rails/pages/ReservedWords

http://coderrr.wordpress.com/2008/04/22/building-the-right-class-with-sti-in-rails/ para resolver o mesmo problema que eu tinha. Eu sou bastante novo para Rails mundo por isso não estou tão certo se essa abordagem é bom ou ruim, mas funciona muito bem. Copiei o código abaixo.

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"}>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top