Muitas pessoas neste segmento e no google explicam muito bem que attr_accessible
especifica uma lista de permissões de atributos que podem ser atualizados em massa ( todos os atributos de um modelo de objeto juntos ao mesmo tempo ) Isso é principalmente (e somente) para proteger seu aplicativo da exploração pirata "Atribuição em massa".
Isso é explicado aqui no documento oficial do Rails: Atribuição em massa
attr_accessor
é um código ruby para (rapidamente) criar métodos setter e getter em uma classe. Isso é tudo.
Agora, o que está faltando como explicação é que, quando você cria de alguma forma um link entre um modelo (Rails) com uma tabela de banco de dados, NUNCA, NUNCA NUNCA precisará NUNCA attr_accessor
no seu modelo para criar setters e getters para poder modificar seu registros da tabela.
Isso ocorre porque seu modelo herda todos os métodos da ActiveRecord::Base
classe, que já define acessadores CRUD básicos (criar, ler, atualizar, excluir) para você. Isso é explicado no documento oficial aqui Modelo do Rails e Substituindo o acessador padrão (role para baixo até o capítulo "Substituir o acessador padrão")
Digamos, por exemplo, que: temos uma tabela de banco de dados chamada "users" que contém três colunas "firstname", "lastname" e "role":
Instruções SQL:
CREATE TABLE users (
firstname string,
lastname string
role string
);
Supus que você definisse a opção config.active_record.whitelist_attributes = true
em seu config / environment / production.rb para proteger seu aplicativo contra a exploração de atribuição em massa. Isso é explicado aqui: Atribuição em massa
Seu modelo Rails funcionará perfeitamente com o modelo aqui abaixo:
class User < ActiveRecord::Base
end
No entanto, você precisará atualizar cada atributo do usuário separadamente no seu controlador para que a Visualização do seu formulário funcione:
def update
@user = User.find_by_id(params[:id])
@user.firstname = params[:user][:firstname]
@user.lastname = params[:user][:lastname]
if @user.save
# Use of I18 internationalization t method for the flash message
flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
end
respond_with(@user)
end
Agora, para facilitar sua vida, você não deseja criar um controlador complicado para o seu modelo de usuário. Então você usará o attr_accessible
método especial no seu modelo de classe:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
end
Então você pode usar a "rodovia" (atribuição em massa) para atualizar:
def update
@user = User.find_by_id(params[:id])
if @user.update_attributes(params[:user])
# Use of I18 internationlization t method for the flash message
flash[:success] = t('activerecord.successful.messages.updated', :model => User.model_name.human)
end
respond_with(@user)
end
Você não adicionou os atributos "role" à attr_accessible
lista porque não permite que seus usuários definam suas funções por si mesmos (como administrador). Você mesmo faz isso em outra tela de administração especial.
Embora a visualização do usuário não mostre um campo "role", um pirata pode facilmente enviar uma solicitação HTTP POST que inclua "role" no hash de parâmetros. O atributo "role" ausente attr_accessible
é o de proteger seu aplicativo disso.
Você ainda pode modificar o atributo user.role por conta própria, como abaixo, mas não com todos os atributos juntos.
@user.role = DEFAULT_ROLE
Por que diabos você usaria o attr_accessor
?
Bem, isso aconteceria se o formulário do usuário mostrar um campo que não existe na tabela de usuários como uma coluna.
Por exemplo, digamos que a visualização do usuário mostre um campo "informe o administrador que estou aqui". Você não deseja armazenar essas informações na sua tabela. Você só quer que o Rails envie um e-mail avisando que um usuário "louco" ;-) se inscreveu.
Para poder usar essas informações, você precisa armazená-las temporariamente em algum lugar. O que é mais fácil do que recuperá-lo em um user.peekaboo
atributo?
Então você adiciona este campo ao seu modelo:
class User < ActiveRecord::Base
attr_accessible :firstname, :lastname
attr_accessor :peekaboo
end
Assim, você poderá fazer um uso instruído do user.peekaboo
atributo em algum lugar do seu controlador para enviar um email ou fazer o que quiser.
O ActiveRecord não salvará o atributo "peekaboo" na sua tabela quando você fizer um, user.save
porque ela não vê nenhuma coluna correspondente a esse nome no modelo dela.
attr_accessor
ao usar os métodos getter e setter. Por favor, veja minha resposta a uma pergunta anterior para obter uma explicação bastante abrangente deattr_accessible
: stackoverflow.com/questions/2652907/…; em seguida, atualize sua pergunta se precisar de outros detalhes específicos depois disso.