ruby 会话控制器中的一些问题

vvppvyoh  于 2023-10-18  发布在  Ruby
关注(0)|答案(1)|浏览(106)

sessions_controller.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

new.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并创建了一个带有create操作的SessionsController来处理表单提交。但是,似乎表单没有被正确处理,我不知道为什么。每当我在这里单击Submit时,它就以前面的方式呈现表单
有人能帮我解决这个问题,并提供一些指导如何解决它?我真的很感激任何援助,在得到表格提交工作正常。

mgdq6dx1

mgdq6dx11#

# add user model v
form_with(model: @user, url: sessions_path, method: :post)

这样生成的输入name属性将是user[email]user[password]。因为您的params必须有一个用户密钥:{user: {email: "myemail", password: "123"}},因为你需要它params.require(:user)
此外,如果你有 Turbo(在rails 7中默认),你需要这个来显示错误响应:

render :new, status: :unprocessable_entity

更新

当你制作表单时,最重要的部分是表单生成器生成的name属性:

<%= 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: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模型。这是不允许的:因为我可以发送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)

如果添加model: @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])中一样。
我是怎么确定的?看看表格,没有model: @user,这意味着上面的所有内容。这是一个普遍的问题。但你所要做的就是看看日志,你可以看到 * 参数 * 和任何错误,不显示在浏览器中。

相关问题