Як видалити поле з парами [: щось]


116

Моя реєстраційна форма, яка є формою для моделі Користувачів, приймає рядкове значення для компанії. Однак я щойно змінив такі зміни, що користувачі належать компаніям. Тому мені потрібно передати об’єкт Компанії моделі користувача.

Я хочу використовувати значення рядка з форми для отримання об'єкта Компанії:

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

Я вважаю, що вищезазначене працює, проте форма переходить: company (яка є рядок) у модель, коли я дзвоню:

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

Тому я хочу знати (і не можу знайти), як видалити параметр: company, перш ніж передати його до моделі користувача.

Відповіді:


209

Рейки 4/5 - відредагована відповідь (див. Коментарі)

Оскільки це питання було написано, новіші версії Rails додали витяг! і крім, наприклад:

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

Це більш безпечний спосіб "схопити" всі потрібні вам параметри в копії БЕЗ знищення оригіналу, переданого в парамах (що НЕ хороша справа, оскільки це з часом налагодить налагодження та підтримку вашого коду).

Або ви можете просто пройти безпосередньо, не копіюючи, наприклад:

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

Оператор extract!(має оператора! Bang) змінить оригінал, тому використовуйте більш уважно!

Оригінальний відповідь

Ви можете видалити пару ключів / значень з Hash, використовуючи Hash#delete:

params.delete :company

Якщо він міститься в парамах [: user], ви користуєтеся цим:

params[:user].delete :company

16
Я використовую Rails 4.0 і model_params.delete :key_nameне працює - будь-яка ідея чому?
Зорайр

13
видалення з парами хешу - це дуже BAD IDEA. легко плутає людей під час налагодження тощо ... використовуйте спеціальний хеш, який ви передаєте, щоб призначити атрибути, наприклад, використовувати assin_params = params.dup.delete(:company). ніколи не видаляйте з
парами

4
я мав на увазіassign_params = params.dup; assign_params.delete(:company)
Домінік Голтерманн

12
@Zorayr У мене була така ж проблема. Для мене це було тому, що моя model_paramsфункція, яка витягувала відповідні парами params. Тож, коли ви deleteз нього, model_paramsви дійсно просто видаляєте хеш, який model_paramsповертається.
Люсі Бейн

1
user_params - це метод, тож коли ви робите user_params.delete (: this_param), він обчислює правильний хеш, але будь-який наступний виклик user_params перерахує хеш з нуля. Ось чому @Gaul сказав, що це погана ідея. У Rails 5 тепер у вас є метод params.except, а також витяг!
rmcsharry

89

Ймовірно, ви повинні використовувати hash.except

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

Він виконує 2 речі: дозволяє виключати більше 1 ключа одночасно, а також не змінювати оригінальний хеш.


Rails 4 ActionController :: Параметри успадковані Hash, так що виключаємо або витягуємо! буде працювати, в Rails 5, у неї є виняток і витяг! методи, визначені в ActionController :: Самі параметри
kangkyu,

У мене фактично є параметри хешу в UPDATE методі. Як я можу, за винятком тих, хто є "-1"ключовим. {"utf8" => "✓", "_method" => "виправлення", "автентичність_token" => "VtY ...", "брошура" => {"title" => "Привіт, світ", "profilings_attributes" => {"-1" => {"member_profile_id" => "3"}, "0" => {"відсоток" => "10.0", "опис" => "Деякий опис!", "_Destroy" = > "false", "id" => "10"}, "1" => {...}}, "sponsing_attributes" => {"-1" => {"sponzor_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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.