#ruby-on-rails #ruby-on-rails-4 #params #ruby-on-rails-4.1
#ruby-on-rails #ruby-on-rails-4 #параметры #ruby-on-rails-4.1
Вопрос:
У меня возникли проблемы, когда я пытаюсь использовать пользовательские параметры.require (…).permit (…)
В моем приложении я получил следующий параметр:
{"utf8"=>"✓",
"authenticity_token"=>"Vatzcb5tgTu2 wL1t6Of FbIK8Ibp tM03Naai4b2OU=",
"/login"=>{"username_or_email"=>"jonatasteixeira",
"password"=>"[FILTERED]"},
"commit"=>"Save /login" }
Я хотел бы знать, почему мой ключ получил имя «/ login».
Мое мнение:
<h1>Login</h1>
<%= form_for(login_path) do |f| %>
<div class="field">
<%= f.label :username_or_email %><br>
<%= f.text_field :username_or_email %>
</div>
<div class="field">
<%= f.label :password %><br>
<%= f.password_field :password %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Back', root_path %>
В моем контроллере
class SessionsController < ApplicationController
# GET /login
def new
@user = User.new
end
# POST /login
def create
@user = User.find_by_emai(session_params[:username_or_email]) || User.find_by_username(session_params[:username_or_email])
if @user amp;amp; @user.authenticate(session_params[:password])
session[:current_user_id] = @user.id
flash[:notice] = 'You are logged in'
else
flash[:notice] = 'Invalid password, username or email'
end
end
private
# Never trust parameters from the scary internet, only allow the white list through.
def session_params
logger.info :login
params.require("/login").permit(:username_or_email, :password)
end
end
Я не хочу использовать «/login» в качестве ключа, я хотел бы использовать:login. Кто-нибудь знает, как я мог бы это настроить?
Спасибо!!
Ответ №1:
Как указал @Rafal, вы могли бы закодировать свой вызов form_for
подобным образом, чтобы избавиться от неудобного /login
ключа в ваших параметрах:
<%= form_for(:login) do |f| %>
Сильные параметры действительно предназначены только для сценариев, в которых вы выполняете массовое присвоение объекту. Например, если бы вы создавали пользователя, то, вероятно, захотели бы передать атрибуты в new
метод инициализатора, используя строгие параметры.
@user = User.new(session_params)
Но поскольку в этом случае вы не выполняете массовое присвоение, вы можете просто передать значения напрямую без session_params
метода:
# POST /login
def create
@user = User.find_by(email: params[:login][:username_or_email]) || User.find_by(username: params[:login][:username_or_email])
if @user amp;amp; @user.authenticate(params[:login][:password])
session[:current_user_id] = @user.id
flash[:notice] = 'You are logged in'
else
flash[:notice] = 'Invalid password, username or email'
end
end
Весь смысл строгих параметров в том, чтобы никто не мог передавать дополнительные атрибуты. В вашем /login
сценарии ваш код полностью контролирует обрабатываемые значения, поэтому вам не нужно беспокоиться об этом.
Комментарии:
1. ХОРОШО .. я сделал это для корректировки, но. Я получаю эту ошибку: «параметр отсутствует или значение пустое: login»
2. Если вы перезагрузите форму и проверите одно из полей, будет ли это выглядеть примерно так?
<input type="text" name="login[username_or_password]" value="" />
3. P.S. Вы должны использовать
find_by(email: ...)
иfind_by(username: ...)
в Rails 4. Я думаю, что динамические средства поиска, такие какfind_by_email
иfind_by_username
, устарели в версии 4.
Ответ №2:
При использовании form_for
Rails ожидает, что object
будет передан, чтобы он мог создавать из него множество различных элементов:
Помощник [form_for] разработан для того, чтобы сделать работу с ресурсами намного проще по сравнению с использованием ванильного HTML.
Проблема в том, что вы передаете маршрут этому методу, который, как я удивлен, действительно работает.
—
Вам будет лучше использовать symbol
, как рекомендовано принятым ответом, или с помощью form_tag
, для которого не требуется объект:
<%= form_tag login_path do %>
<%= text_field_tag :username_or_email %>
<%= password_field_tag :password %>
<%= submit_button_tag "Go" %>
<% end %>
Это удалит ссылки на ключ «login» ваших параметров и даст вам возможность сделать это (в этом нет необходимости require
):
params.permit(:username_or_email, :password)
Ответ №3:
Вместо
<%= form_for(login_path) do |f| %>
использовать
<%= form_for(:login) do |f| %>
Комментарии:
1. Я сделал это, но это не исправило мою проблему, параметры остаются iqual!