Измените хеш-рубин на месте (сильные параметры рельсов)
Это может быть более рубиновый вопрос, чем вопрос рельсов, но я уверен, что смог сделать это в ванильном рубиновом приложении.
У меня есть сильные параметры.
def trip_params
params.require(:trip).permit(:name, :date)
end
Теперь я получаю эти параметры в методе контроллера. Я хочу это сделать.
def save
trip_params[:name] = 'Modifying name in place'
#trip_params[:name] still equals original value passed
end
Это никогда не работает. Имя никогда не изменяется.
BTW: Тип trip_params - ActionController:: Параметры
Если я делаю стандартный ruby script, он работает.
test = {}
test[:name] = "blah"
test[:name] = "ok"
puts test #{:name=>"ok"}
Ответы
Ответ 1
permit
возвращает новый хеш с этими ключами в нем, поэтому вы не изменяете реальную переменную params
. Вы также не сохраняете ссылку на хеш trip_params, поэтому вы получаете свежий каждый вызов в save
.
Попробуйте следующее:
def save
tp = trip_params
tp[:name] = 'Modifying name in place'
# ... use tp later, it'll be in there
end
Или, если вы действительно хотите, чтобы его использовали так, как вы это делали ранее, измените trip_params
так:
def trip_params
@trip_params ||= params.require(:trip).permit(:name, :date)
end
Теперь этот хэш лениво кэшируется, а тот же возвращается при последующих вызовах trip_params
.
Ответ 2
Если вы действительно хотите изменить параметры в контроллере, вы можете сделать это следующим образом:
def save
params[:trip][:name] = 'Modifying name in place'
# Now trip_params[:name] is 'Modifying name in place'
end
Ответ 3
Это потому, что нет метода, такого как trip_params[]=(arg, val).
Я имею в виду, когда вы вызываете trip_params, вы возвращаете значение params.require(:trip).permit(:name, :date)
, поэтому каждый раз, когда вы вызываете trip_params
, вы снова получаете параметры.
Итак, если бы я был вами, я бы определил метод trip_params следующим образом:
def trip_params
@trip_params ||= params.require(:trip).permit(:name, :date)
end
И также будет определять способ изменения trip_params
def trip_params[]= (key,val)
trip_params # Ensure that trip_params is called once or you will get an error
@trip_params[key] = val
end
Итак, теперь, когда вы вызываете trip_params
, вы действительно возвращаете @trip_params
, а если @trip_params
еще не установлен, он будет установлен на params.require(:trip).permit(:name, :date)
И затем, когда вы вызываете trip_params[:name] = "Some name"
, сначала убедитесь, что @trip_params
инициализируется вызовом trip_params and then it will set the :name param to
"Некоторое имя" `
Надеюсь, я помог вам
Ответ 4
Вы также можете сделать
def save
data = trip_params.merge(name: 'new name')
# use data later
end
Если новый хэш объединяется в старый хеш, и если есть повторяющиеся ключи, новые хеш-ключи перезаписывают старые хеш-ключи.
👍🏼