Como remover um campo de parâmetros [: algo]

116

Meu formulário de registro, que é um formulário para o modelo Usuários, assume um valor de string para empresa. No entanto, acabei de fazer uma alteração para que os usuários pertençam a empresas. Portanto, preciso passar um objeto da Empresa para o modelo Usuários.

Quero usar o valor da string do formulário para obter um objeto da Empresa:

@user.company = Company.find_by_name(params[:company])

Acredito que o acima funcione, mas a forma está passando: company (que é string) para o modelo quando eu chamo:

@user = User.new(params[:user])

Portanto, desejo saber (e não consigo encontrar como) remover o parâmetro: company antes de passá-lo para o modelo de usuário.

providência
fonte

Respostas:

209

Rails 4/5 - resposta editada (ver comentários)

Desde que esta questão foi escrita, novas versões do Rails adicionaram o extrato! e exceto por exemplo:

new_params = params.except[the one I wish to remove]

Esta é uma maneira mais segura de 'pegar' todos os parâmetros que você precisa em uma cópia SEM destruir o original passado nos parâmetros (o que NÃO é uma boa coisa a se fazer, pois tornará a depuração e manutenção de seu código muito difícil com o tempo).

Ou você pode simplesmente passar diretamente sem copiar, por exemplo:

@person.update(params[:person].except(:admin))

O extract!(tem o operador! Bang) modificará o original, portanto, use com mais cuidado!

Resposta Original

Você pode remover um par chave / valor de um Hash usando Hash#delete:

params.delete :company

Se estiver contido em params [: user], você usaria este:

params[:user].delete :company
Jeremy Ruten
fonte
16
Estou usando Rails 4.0 e model_params.delete :key_namenão funciona - alguma ideia do porquê?
Zorayr
13
excluir do hash de parâmetros é uma ideia muito RUIM. confunde as pessoas facilmente durante a depuração, etc ... use um hash personalizado que você passa para atribuir atributos, por exemplo, use assin_params = params.dup.delete(:company). nunca exclua dos parâmetros diretamente
Dominik Goltermann
4
eu quis dizerassign_params = params.dup; assign_params.delete(:company)
Dominik Goltermann
12
@Zorayr Eu tive o mesmo problema. Para mim, foi porque meu model_paramsera uma função, que puxou os parâmetros relevantes de params. Então, quando você deletede model_paramsque você está realmente apenas apagar a partir do hash que model_paramsretorna.
Lucy Bain
1
user_params é um método, então quando você faz user_params.delete (: this_param), ele calcula o hash correto, mas qualquer chamada subsequente para user_params irá recalcular o hash do zero. É por isso que @Gaul disse que é uma má ideia. No Rails 5 você agora tem o método params.except e também extract!
rmcsharry
89

Você provavelmente deveria estar usando hash.except

class MyController < ApplicationController
  def explore_session_params
    params[:explore_session].except(:account_id, :creator)
  end
end

Ele realiza 2 coisas: permite que você exclua mais de 1 chave por vez e não modifica o hash original.

samuraisam
fonte
Rails 4 ActionController :: Parameters herdou o Hash, portanto, exceto ou extrair! funcionaria, no Rails 5, ele tem exceto e extrair! métodos definidos no próprio ActionController :: Parameters
kangkyu
Na verdade, tenho esses parâmetros de hash no método UPDATE. Como posso excluir quem tem "-1"como chave. {"utf8" => "✓", "_method" => "patch", "authenticicity_token" => "VtY ...", "flyer" => {"title" => "Hello world", "profilings_attributes" => {"-1" => {"member_profile_id" => "3"}, "0" => {"porcentagem" => "10.0", "descrição" => "Alguma descrição!", "_Destroy" = > "false", "id" => "10"}, "1" => {...}}, "sponsorings_attributes" => {"-1" => {"sponsor_id" => "2"}, "0" => {"flyer_id" => "
2

A maneira correta de conseguir isso é usando strong_params

class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
  end

  private

  def user_params
    params.require(:user).permit(:name, :age)
  end
end

Desta forma, você tem mais controle sobre quais parâmetros devem ser passados ​​para o modelo

Deepak Mahakale
fonte
1
respond_to do |format|
  if params[:company].present?
    format.html { redirect_to(:controller => :shopping, :action => :index) }
  else
    format.html
  end
end

isto irá remover os parâmetros do url

Taimoor Changaiz
fonte
0

Para ser possível excluir, você pode fazer um memorando :

def parameters
  @parameters ||= params.require(:root).permit(:foo, :bar)
end

Agora você pode fazer:

parameteres.delete(:bar)
parameters
=> <ActionController::Parameters {"foo" => "foo"} permitted: true>
Washington Botelho
fonte