我之前从未为web开发任何东西,但现在我必须创建一个简单的应用程序来显示现有数据库中的一些数据。
事实是,每个用户应该只看到他/她的相应数据,所以我需要某种形式的身份验证来查询加入该用户和其他表的查询。我试图保持简单,所有用户必须做的是输入它的用户名,这是Pessoa表上的主键(没有密码,没有电子邮件确认,没有任何内容)。
我已经阅读了一些有关RailsGuails上的Rails的教程,以及www.rubypigeon.com/posts/how-to-implement-simple-authentication-without-devise/进行身份验证,但我可以&#39 ;让我的登录工作。
到目前为止,这是我的代码:
HomeController中:
class HomeController < ApplicationController
def index
end
def login
@user = Pessoa.new
end
def sign_in
@user = Pessoa.find(params[:id])
if @user
session.clear
session[:user_id] = @user.id
render '/'
else
@error = 'Username or password was incorrect'
erb :sign_in
end
end
def sign_out
session.clear
render '/'
end
helper_method :current_user
def current_user
if session[:user_id]
Pessoa.find (session[:user_id])
else
nil
end
end
end
视图/家/ login.html.erb:
<%= form_for @user, url: home_sign_in_path do |f| %>
<div class="field">
<%= f.label :"digite seu login" %>
<%= f.text_field :id %>
</div>
<div class="actions">
<%= f.submit :entrar %>
</div>
<% end %>
的routes.rb
Rails.application.routes.draw do
root 'home#index'
get 'home/index'
get 'home/login', to: 'home#login'
post 'home/sign_in', to: 'home#sign_in'
post 'home/sign_out', to: 'home#sign_out'
resources :pessoas
end
/views/home/index.html.erb有很多静态HTML的东西,唯一的Ruby代码就是
<%= link_to 'Login', home_login_path %>
Pessoa.rb
class Pessoa < ApplicationRecord
self.table_name = 'pessoa'
self.primary_key = 'login'
end
我正在使用PostgreSQL上的旧表,这就是为什么必须更改主键的原因。
每当我去localhost:3000 / home / login并输入我的登录信息时,我都会this 错误信息。奇怪的是,如果我运行完全相同的行,在控制台上给我错误,它就可以正常工作。
正如我所说,我对Rails和Web开发一般都很陌生,所以我认为这是一个我无法看到的细节。任何帮助将不胜感激。
不过,请注意资源名称,&#34; Pessoa&#34;意味着&#34;人&#34;用葡萄牙语,这是我的母语。development.log:
Started GET "/home/login" for 127.0.0.1 at 2017-06-06 20:22:45 -0300
Processing by HomeController#login as HTML
Rendering home/login.html.erb within layouts/application
Rendered home/login.html.erb within layouts/application (12.4ms)
Completed 200 OK in 1504ms (Views: 1369.5ms | ActiveRecord: 0.0ms)
Started POST "/home/sign_in" for 127.0.0.1 at 2017-06-06 20:22:50 -0300
Processing by HomeController#sign_in as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Jzt0Yeven91Kl8DrfjpJa8I9PJjr7SzKmE43lwprjlopV7l+zFU6EUjUgAiKYJhzemm7xu8NGfiPj3E5h5EiYw==", "pessoa"=>{"id"=>"gabrielbrito"}, "commit"=>"entrar"}
[1m[36mPessoa Load (1.5ms)[0m [1m[34mSELECT "pessoa".* FROM "pessoa" WHERE "pessoa"."login" = $1 LIMIT $2[0m [["login", nil], ["LIMIT", 1]]
Completed 404 Not Found in 9ms (ActiveRecord: 1.5ms)
ActiveRecord::RecordNotFound (Couldn't find Pessoa with 'login'=):
app/controllers/home_controller.rb:10:in `sign_in'
Started PUT "/__web_console/repl_sessions/ed3bb60f3a72a0c0b0c951fa03c0f23d" for 127.0.0.1 at 2017-06-06 20:22:56 -0300
Started PUT "/__web_console/repl_sessions/ed3bb60f3a72a0c0b0c951fa03c0f23d" for 127.0.0.1 at 2017-06-06 20:22:58 -0300
Started PUT "/__web_console/repl_sessions/ed3bb60f3a72a0c0b0c951fa03c0f23d" for 127.0.0.1 at 2017-06-06 20:23:04 -0300
[1m[36mPessoa Load (1.2ms)[0m [1m[34mSELECT "pessoa".* FROM "pessoa" WHERE "pessoa"."login" = $1 LIMIT $2[0m [["login", "gabrielbrito"], ["LIMIT", 1]]
Started GET "/home/login" for 127.0.0.1 at 2017-06-06 21:27:45 -0300
Processing by HomeController#login as HTML
Rendering home/login.html.erb within layouts/application
Rendered home/login.html.erb within layouts/application (6.2ms)
Completed 200 OK in 1626ms (Views: 1152.5ms | ActiveRecord: 7.5ms)
Started POST "/home/sign_in" for 127.0.0.1 at 2017-06-06 21:27:52 -0300
Processing by HomeController#sign_in as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"q2ffWM1gqaXfCrsFm7KlGKwR/iTDoQBflquem2BKSaeMyKBiIaUrtnIkoEXNztUWRasIGGg0qZZxpdYao8xb9Q==", "pessoa"=>{"id"=>"gabrielbrito"}, "commit"=>"entrar"}
[1m[36mPessoa Load (2.8ms)[0m [1m[34mSELECT "pessoa".* FROM "pessoa" WHERE "pessoa"."login" = $1 LIMIT $2[0m [["login", "gabrielbrito"], ["LIMIT", 1]]
Completed 500 Internal Server Error in 23ms (ActiveRecord: 2.8ms)
NoMethodError (undefined method `empty?' for nil:NilClass):
app/controllers/home_controller.rb:15:in `sign_in'
编辑:解决了,感谢@ Gerry的帮助。
答案 0 :(得分:0)
<强>更新强>
您的模型中似乎是self.primary_key = 'login'
的问题,因此请尝试将该密钥添加到您的路线中:
resources :pessoas, param: :login
为了保持一致,您还应该将id
的任何引用更改为login
,即在您的控制器中:
@user = Pessoa.find_by(login: params[:pessoa][:login])
在你看来:
<div class="field">
<%= f.label :"digite seu login" %>
<%= f.text_field :login %>
</div>
关于
“未定义的方法”为空? for nil:NilClass“on line render'/'
您应该将render '/'
更改为redirect_to
(重定向到其他页面)或render view_name
,其中view_name
是您要呈现的视图的名称。< / p>
例如,如果要重定向到主页,可以执行以下操作:
redirect_to home_path
此外,您应该使用find_by
而不是find
来避免在用户输入无效login
(即DB中不存在的那个)时出现相同的错误:
@user = Pessoa.find_by(login: params[:pessoa][:login])
由于这种方式您将获得一个空集合而不是错误(异常),您还需要更新评估是否找到User
的方式:
if @user.present?
# success code
else
# failure code
end
总而言之,您的sign_in
行动应如下所示:
def sign_in
@user = Pessoa.find_by(login: params[:pessoa][:login])
if @user.present?
session.clear
session[:user_id] = @user.id
redirect_to home_path
else
@error = 'Username or password was incorrect'
end
end