Как удалить поле из params [: something]

116

Моя регистрационная форма, которая является формой для модели Users, принимает строковое значение для компании. Однако я только что внес изменение, чтобы пользователи принадлежали компаниям. Поэтому мне нужно передать объект Company в модель Users.

Я хочу использовать строковое значение из формы для получения объекта Company:

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

Я считаю, что это работает, однако форма передает: company (которая является строкой) в модель, когда я вызываю:

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

Поэтому я хочу знать (и не могу найти, как) удалить параметр: company, прежде чем передавать его модели User.

провидение
источник

Ответы:

209

Rails 4/5 - отредактированный ответ (см. Комментарии)

Поскольку этот вопрос был написан, более новые версии Rails добавили отрывок! и кроме, например:

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

Это более безопасный способ «захватить» все нужные вам параметры в копию БЕЗ уничтожения оригинала, переданного в params (что НЕ рекомендуется, поскольку со временем это сильно усложнит отладку и обслуживание вашего кода).

Или вы можете просто пройти напрямую, не копируя, например:

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

extract!(Имеет оператор бах!) Будет изменять оригинал так использования с большей осторожностью!

Оригинальный ответ

Вы можете удалить пару ключ / значение из хэша, используя Hash#delete:

params.delete :company

Если он содержится в params [: user], вы должны использовать это:

params[:user].delete :company
Джереми Рутен
источник
16
Я использую Rails 4.0 и model_params.delete :key_nameне работаю - не знаете почему?
Зорайр
13
удаление из хэша params - очень ПЛОХАЯ ИДЕЯ. легко сбивает людей с толку во время отладки и т. д. используйте специальный хэш, который вы передаете для назначения атрибутов, например, use assin_params = params.dup.delete(:company). никогда не удаляйте напрямую из params
Доминик Гольтерманн
4
я имел в видуassign_params = params.dup; assign_params.delete(:company)
Доминик Гольтерманн
12
@Zorayr У меня была такая же проблема. Для меня это было потому, что my model_paramsбыла функцией, которая вытащила соответствующие параметры из params. Итак, когда вы deleteиз, model_paramsвы действительно просто удаляете из хэша, который model_paramsвозвращается.
Люси Бейн
1
user_params - это метод, поэтому, когда вы выполняете user_params.delete (: this_param), он вычисляет правильный хеш, но любой последующий вызов user_params будет пересчитывать хеш с нуля. Вот почему @Gaul сказал, что это плохая идея. В Rails 5 теперь есть метод params.except, а также extract!
rmcsharry
89

Вероятно, вам следует использовать hash.except

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

Он выполняет 2 вещи: позволяет исключать более 1 ключа за раз и не изменяет исходный хэш.

samuraisam
источник
Rails 4 ActionController :: Параметры унаследованы от Hash, поэтому исключить или извлечь! будет работать, в Rails 5 есть except и extract! методы, определенные в самом ActionController :: Parameters
kangkyu
На самом деле у меня есть эти параметры хэша в методе UPDATE. Как я могу кроме тех, у кого "-1"ключ? {"utf8" => "✓", "_method" => "patch", "Authentity_token" => "VtY ...", "brochure" => {"title" => "Hello world", "profilings_attributes" => {"-1" => {"member_profile_id" => "3"}, "0" => {"percent" => "10.0", "description" => "Немного описания!", "_Destroy" = > "false", "id" => "10"}, "1" => {...}}, "спонсорские_атрибуты" => {"-1" => {"спонсор_id" => "2"}, "0" => { "brochure_id" =>»
2

Правильный способ добиться этого - использовать 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

Таким образом, у вас будет больше контроля над тем, какие параметры следует передавать в модель.

Дипак Махакале
источник
1
respond_to do |format|
  if params[:company].present?
    format.html { redirect_to(:controller => :shopping, :action => :index) }
  else
    format.html
  end
end

это удалит параметры из URL-адреса

Таймор Чангайз
источник
0

Чтобы можно было удалить, вы можете сделать памятку :

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

Теперь вы можете:

parameteres.delete(:bar)
parameters
=> <ActionController::Parameters {"foo" => "foo"} permitted: true>
Вашингтон Ботельо
источник