セッションコントローラーに何らかの問題がある
概要
セッションコントローラー.rb
class SessionsController < ApplicationController
def new
@user = User.new
end
def create
@user = User.find_by(email: user_params[:email])
if @user && @user.password == user_params[:password]
cookies[:user_id] = @user.id
redirect_to blogs_path
else
flash.now[:notice] = "invalid email or password"
render :new
end
end
private
def user_params
params.require(:user).permit(:email,:password)
end
end
新しい.html.erb
<p id="notice"><%= notice %></p>
<h1> Sign in </h1>
<%= form_with(url: sessions_path, method: :post) do |form| %>
<div>
<%= form.label :email %>
<%= form.text_field :email %>
</div>
<div>
<%= form.label :password %>
<%= form.password_field :password %>
</div>
<%= form.submit "Submit" %>
<% end %>
私は Rails を使用しており、フォームの送信を処理する作成アクションを備えた SessionsController を作成しました。ただし、フォームが正しく処理されていないようで、その理由がわかりません。これで送信をクリックすると、以前の方法でフォームがレンダリングされるだけです
誰かがこの問題のトラブルシューティングを手伝ってくれ、修正方法についてのガイダンスを提供してもらえますか?フォームの送信が適切に機能するよう支援していただければ幸いです。
解決策
# add user model v
form_with(model: @user, url: sessions_path, method: :post)
この方法で生成される入力名の属性は、user[email] と user[password] になります。 params.require(:user) を必要としているため、params にはユーザー キーが必要です: {user: {email: “myemail”, password: “123”}}。
また、Turbo を使用している場合にエラー応答を表示するには、これが必要になります (Rails 7 ではデフォルトで使用されています)。
render :new, status: :unprocessable_entity
アップデート
フォームを作成するときに最も重要な部分は、フォーム ビルダーによってどのような名前属性が生成されるかです。
<%= form_with url: "/sign_in", method: :post do |f| %>
<%= f.text_field :email %>
<%#=> <input type="text" name="email"> %>
<% end %> # ^^^^^
<%= form_with model: @user, url: "/sign_in", method: :post do |f| %>
<%= f.text_field :email %>
<%#=> <input type="text" name="user[email]"> %>
<% end %> # ^^^^^^^^^^^
form_with がどのように機能するかを知っておく必要があるだけです。 https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_with
フォームを送信すると、SessionsController#create に移動します。送信されたフォーム パラメーターは Rails によって解析され、params ヘルパーで利用できます。URL エンコードされたパラメーターの場合、次のようになります。
# name=value
>> Rack::Utils.parse_nested_query("email=asdf")
=> {"email"=>"asdf"}
>> Rack::Utils.parse_nested_query("user[email]=asdf")
=> {"user"=>{"email"=>"asdf"}}
デフォルトでは、params は ActionController::Parameters オブジェクトを返します。ユーザーモデルにパラメーターを与えるためには、パラメーターを許可する必要があります。これは許可されません: User.create(params) は、email=myemail&superadmin=true を送信できる可能性があり、現在は私が担当しているためです。
コントローラーでは、最初に次の呼び出しが行われます。 user_params[:email] => params.require(:user).permit(:email,:password)
>> parameters = Rack::Utils.parse_nested_query("email=myemail")
>> params = ActionController::Parameters.new(parameters)
# ^ this is what you have
# v this is what happens (you have to look at server logs)
>> params.require(:user)
/home/alex/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/actionpack-7.0.4.3/lib/action_controller/metal/strong_parameters.rb:500:in `require':
param is missing or the value is empty: user (ActionController::ParameterMissing)
モデルを追加する場合: @user:
>> parameters = Rack::Utils.parse_nested_query("user%5Bemail%5D=myemail")
>> params = ActionController::Parameters.new(parameters)
>> params.require(:user)
=> #<ActionController::Parameters {"email"=>"myemail"} permitted: false>
>> params.require(:user).permit(:email)
=> #<ActionController::Parameters {"email"=>"myemail"} permitted: true>
# ^
# everything else should work from this point
User.find(params[:id]) のように、個々の属性を取得するときは、params を許可する必要がないことに注意してください。
これをどうやって判断したのでしょうか?フォームを見てください。モデルがありません: @user は、上記の ^ をすべて意味します。それはよくある問題です。ただし、ログを確認するだけで、パラメータやブラウザに表示されないエラーを確認できます。