Reputation: 7
I'm checking if a record exists in my database, but it keeps returning false even when it does exist. I tried in rails's console aswell it returns true, but in my app it doesn't work i can't seem to find why ? Update (full code):
class FormulaireController < ApplicationController
def index
@accounts = Account.all
@account = session[:logged] ? Account.find_by(username: session[:username]) : Account.new
end
def create
if params[:loginbtn]
if Account.exists?(account_params)
@account = Account.find_by(username: params[:username])
session[:username] = @account.username
session[:logged] = true
redirect_to root_path, notice: "Hello, #{@account.username}! You successfully logged in!" and return
else
redirect_to root_path, notice: "Invalid username or password. Create a new account ?" and return
end
else
@account = Account.new(account_params)
if Account.exists?(:username => @account.username)
redirect_to root_path, notice: "Username already taken !" and return
elsif @account.save
session[:username] = @account.username
session[:logged] = true
redirect_to root_path, notice: "Hello, #{@account.username}! You successfully created your account!" and return
end
end
render 'index'
end
def logout
if session[:logged]
reset_session
redirect_to root_path, notice: "Successfully logged out !" and return
end
render 'index'
end
private
def account_params
params.require(:account).permit(:username, :password)
end
end
i know this is not secure at all, but this is just to learn rails i am a beginner.
heres my form:
<%= form_for @account, url: create_path, method: :post do |f| %>
<div class="input-group col-xs-6">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<%= f.text_field :username, class: "form-control" %>
</div><br>
<div class="input-group col-xs-6">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<%= f.password_field :password, class: "form-control" %>
</div><br>
<div class="form-group">
<% if session[:logged] %>
<%= link_to "Disconnect", logout_path, class: "btn btn-primary" %>
<% else %>
<%= f.submit "Login", name: "loginbtn", class: "btn btn-primary" %>
<% end %>
<%= f.submit "Register", name: "registerbtn", class: "btn btn-success" %>
</div>
<% end %>
routes.rb:
Rails.application.routes.draw do
root :to => 'formulaire#index'
get '/logout' => 'formulaire#logout'
post '/create' => 'formulaire#create'
end
i checked manually for params and it returns the correct value, i also check my DB it's correct, but it keeps returning false when i use exists? method
Update (console log):
Started POST "/create" for 127.0.0.1 at 2017-06-29 19:29:27 +0200
Processing by FormulaireController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ttElLyvYuuGY1noKEfT7Vqg7HY2sFJehi/ZgESRftjwbBzVQVS7uOKvEADbYiCuw9xJNIZGICrM36c9x2hWKCQ==", "account"=>{"username"=>"Henrygolant", "password"=>"[FILTERED]"}, "loginbtn"=>"Login"}
Account Load (0.2ms) SELECT `accounts`.* FROM `accounts` WHERE `accounts`.`username` IS NULL LIMIT 1
Redirected to http://localhost:3000/
Completed 302 Found in 2ms (ActiveRecord: 0.2ms)
Started GET "/" for 127.0.0.1 at 2017-06-29 19:29:27 +0200
Processing by FormulaireController#index as HTML
Rendering formulaire/index.html.erb within layouts/application
Account Exists (0.2ms) SELECT 1 AS one FROM `accounts` LIMIT 1
Account Load (0.2ms) SELECT `accounts`.* FROM `accounts`
Rendered formulaire/index.html.erb within layouts/application (2.9ms)
Completed 200 OK in 28ms (Views: 26.7ms | ActiveRecord: 0.3ms)
Upvotes: 0
Views: 881
Reputation: 20263
You should do it more like this:
def create
if params[:loginbtn]
if @account = Account.find_by(username: params[:account][:username])
session[:username] = @account.username
session[:logged] = true
redirect_to root_path, notice: "Hello, #{@account.username}! You successfully logged in!" and return
else
redirect_to root_path, notice: "Invalid username or password. Create a new account ?" and return
end
else
@account = Account.new(account_params)
if @account.save?
session[:username] = @account.username
session[:logged] = true
redirect_to root_path, notice: "Hello, #{@account.username}! You successfully created your account!" and return
else
redirect_to root_path, notice: "Username already taken !" and return
end
end
render 'index'
end
In the case of login, if @account
is nil (i.e., is not found/doesn't exist), then you'll fall through to your else statement.
In the case of register, if @account.save
fails (i.e., is not valid because user name is already taken), then you also fall through to your else statement.
Also, I'm not sure you need:
elsif params[:registerbtn]
Unless there's some other way to submit the form. So maybe just else
.
Pavan's suggestion is a good one. In which case, this could become:
def create
if @account = Account.find_or_create_by(account_params)
session[:username] = @account.username
session[:logged] = true
redirect_to root_path, notice: "Hello, #{@account.username}! You successfully logged in!" and return
else
redirect_to root_path, notice: "Invalid username or password. Create a new account ?" and return
end
render 'index'
end
Upvotes: 0
Reputation: 33542
I checked manually for params and it returns the correct value, i also check my DB it's correct, but it keeps returning false when i use exists? method
The exists? method expects either Integer/String/Array/Hash as a argument
, but you are passing account_params
which is an instance of ActionController::Parameters
. So it always returns false
.
It seems like find_or_create_by could be a best fit for what you are trying to do
Upvotes: 2