undefined method `session' for ApplicationController:Class - ruby-on-rails

I am practicing with rails and I was in the topic of "session" and I get the message
"undefined method `session' for ApplicationController:Class"
please help me
this is the code
*(controller aplication)
class ApplicationController < ActionController::Base
session :session_key => 'ruby_cookies'
end
*(controller when I want to create the cookies)
class RegistroController < ApplicationController
def index
end
def login
if request.post?
p_user = User.new(params[:user])
user = User.find_by_nombre_and_password(p_user.nombre, p_user.password)
if user
session[:user_id] = user.id
flash[:notice] = "se ha identificado correctamente"
redirect_to home_url
else
flash[:notice] = "se incorrecto psps"
redirect_to login_url
end
end
end
def logout
session[:user_id] = nil
flash[:notice] = "adios sayonara"
redirect_to home_url
end
end

Your code is really hard to read, but the issue is probably related to this line where it looks like it's trying to call a method "session" and pass it a key/value pair.
session :session_key => 'ruby_cookies'
This doesn't appear to be within any sort of controller action. Normally you would set a session value with session[:my_value] = 'value' and read it with session[:my_value], just like a normal hash.

Your code in ApplicationController doesn't belong there. It belongs in a configuration file, for example config/environment.rb, where it would read something like this:
config.action_controller.session = {
:session_key => 'ruby_cookies'
}
See http://guides.rubyonrails.org/configuring.html for much more detail.

Related

NoMethodError in UserController#register undefined method `save' for nil:NilClass

Trying to learn ruby on rails following Michael Hartl's tutorial, when I try to go to the registration page in the book I get this:
NoMethodError in UserController#register
undefined method `save' for nil:NilClass
here is the code from the user_controller.rb file:
class UserController < ApplicationController
def index
#title = "RailsSpace User Hub"
end
def register
#title = "Register"
if request.post? and params[:user]
#user = User.new(user_params)
end
if #user.save
flash[:notice] = "User #{#user.screen_name} created!"
redirect_to :action => "index"
end
end
private
def user_params
# Add the user attributes that you sent with post (form) to the permit
method.
params.require(:user).permit(:name, :screen_name)
end
end
It's complaining about line 11 where it says: if #user.save I'm just following the tutorial I don't know what's going on.
Try to understand what the error message is saying. You're trying to call .save on #user but where you are calling it, #user may not be defined. The problem is you can't call .save on a nil object so it throws NoMethodError.
You're logic is incorrect so you must first make sure #user is instantiating a new User instance. It should be more like this:
def register
#title = "Register"
if request.post? && params[:user]
#user = User.new(user_params)
if #user.save
flash[:notice] = "User #{#user.screen_name} created!"
redirect_to :action => "index"
else
# handle erorrs here
flash[:alert] = "Please fix errors: #{#user.errors.full_messages.inspect}"
redirect_to :back #this may need to change depending, just an example.
end
end
end
NoMethodError in UserController#register undefined method 'save' for nil:NilClass
The error is thrown because you are calling save on a nil; and it is because nil object does not have this method. the save is a instance method belonging to ActiveRecord::Base class.
The reason #user is nil is because #user is an instance variable in the UserController class which you have not given it any value. Any variable starting with # inside a class is an instance variable in Ruby.
To solve this problem, you should set a value to #user, and in this case it should be a User instance. You can either create a new user object by doing #user = User.new(user_params) or you fetch a record from the Database by doing #user = User.find(<some_id>)

Ruby on rails get id from instance variable

I have an instance variable #user
so in HTML <%=link_to #user %> gives me the result:
{"id"=>2, "restaurant"=>"sea food", "password"=>"123", "name"=>"a", "email"=>"a", "telephone"=>"123", "created_at"=>"2016-10-09T04:00:24.010Z", "updated_at"=>"2016-10-09T04:00:24.010Z"}
I want to get the value of id, but when I write:<%=link_to #user[:id] %> it returns me the result :/restaurant/home, which is the route of my home function inside my restaurant controller and I can't understand why.
This is my controller:
class RestaurantController < ApplicationController
def home
#user = session['loginedUser']
end
def login
end
def checkLogin
#user = User.find_by_restaurant(params[:user][:restaurant])
if #user != nil && #user[:password] == params[:user][:password]
session['loginedUser'] = #user
redirect_to :controller=>'restaurant',:action=>'home'
else
session['loginedUser'] = nil
# redirect_to :controller=>'restaurant',:action=>'login'
end
end
def logout
session['loginedUser'] = nil
redirect_to :controller=>'restaurant',:action=>'home'
end
end
Can anybody help?
Thanks a lot.
You should not save complex objects within your session object. Session data is saved within a cookie by default and many browsers accept only cookies until 4kB. Other issues exists too.
I suggest this change:
def checkLogin
...
session['loginedUser'] = #user.id
...
end
def home
#user = User.find session['loginedUser']
end
Your link to should look like this
<%=link_to id: #user.id %>. This solution is not realy Rails like. There should be an appropriate helper. You can check your routes with rake routes | grep home. You will see something like xxx_xxx_home_xxx_restaurant /restaurant/home(.format) restaurant#home. The first part is the helper name and you can add _path or _url. This may look like <%=link_to xxx_xxx_home_xxx_restaurant_path id: #user.id %>

Rails session[:user_id] wont destroy

Im new to Rails and having troubles trying to destroy the user session.
My session controller looks like this
class SessionsController < ApplicationController
def new
end
def create
name = params[:name]
password = params[:password]
user = User.authenticate(name, password)
if user.nil?
render json: {isLogin: false}
else
session[:user_id] = user.id
render json: {isLogin: true}
end
end
def destroy
session[:user_id] = nil
puts session[:user_id] # Nothing gets printed to the console here
render json: {isLogin: false}
end
end
When I call 'sessions/destroy' and try to destroy the session, nothing gets printed at 'puts session[:user_id]' line. So I know for sure that the session is nil at that point. But the problem is that I can still access the session like this from a different controller even after I destroy the session for that user.
class LessonsController < ApplicationController
def getLesson
userId = session[:user_id]
# do stuff
end
end
Why is this happening? and how can I fix this?.
Try
session.delete(:user_id)
instead of
session[:user_id] = nil
That is what I have had luck with in the past.

How I Pass parameters from View to Controller In Ruby

#app/controllers/sessions_controller.rb
class SessionController < ApplicationController
def new
#session = Session.new
end
def fetch
##user = User.session(params [:user])
redirect_to "http://www.google.com"
end
def create
emai = params[:email]
puts emai
user = User.find_by(:email => session[:emai])
#user = User.find_by (params [:email])
#user = User.find_by email: 'abc#xyz.com'
#user = User.find_by(params[:Email])
#if (session[:Email] = user.email)
if (user)
redirect_to "http://www.yahoo.com"
flash[:notice] = "You signed up successfully"
flash[:color]= "valid"
else
flash[:notice] = "Form is invalid"
flash[:color]= "invalid"
redirect_to "http://www.google.com"
end
#redirect_to "http://www.yahoo.com"
end
end
every time i execute my view i get redirected to google.com even though i pass the parameters.
Edit by R Peck:
My logic should send people to Yahoo if the params are set, but still sends to Google, how can I fix this?
Try:
user = User.find_by(:email => params[:sessions][:emai])
You are not getting the value of email if you only call params[:email] you should call parent first before calling the child params[:sessions][:email].
Several things wrong with your code.
Here's what I'd write:
#app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
#session = Session.new
end
def create
email = params[:sessions][:email]
user = User.find_by email: email
url = user ? "google" : "yahoo"
colour = user ? "valid" : "invalid"
notice = user ? "You signed up successfully" : "Your form is invalid"
redirect_to "http://#{url}.com", notice: notice, color: colour
end
private
def session_params
params.require(:session).permit(:session, :params)
end
end
OOP
I think this may be a little advanced but I'll write it anyway, for my own benefit.
Rails is object orientated (it's built on Ruby which is an OOP language). This means that each time you create/call a controller, it should be centered around objects.
A good example for you would be the Devise controllers.
This has a sessions_controller which essentially allows you to CRUD (Create Read Update Destroy) a session. This is the correct way to use a controller.
Your implementation seems to be dealing with a user, rather than a session, and as such you'd be best using a users_controller to fix it:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new
#user.save
end
end
Having said that, it does seem that you're probably going to resolve the issue to make it so that you can use the User to build a new session.
I guess it's best to remember that you have to ensure you're able to appreciate a good structure for your application

Setter method for current_user never being used

So I am building an application that I am trying to never need a database as the application will just be a portal to an API. I have a sessions controller and I am trying to use a cookie based session but the setter method is never being hit. Here is what I have at this point.
sessions_controller.rb
class SessionsController < ApplicationController
def new
if current_user
redirect_to snapshots_path
end
end
def create
api = API.new
response = api.authenticate_user(params[:session][:username].downcase, params[:session][:password])
if response["Message"] == "success"
current_user = response["User"]
binding.pry
redirect_to snapshots_path, notice: "Signed in successfully."
else
flash.now[:error] = "Invalid username/password combination."
render :new
end
end
def destroy
current_user = nil
redirect_to sign_in_path
end
end
sessions_helper.rb
module SessionsHelper
def current_user=(user)
binding.pry
if user
#current_user = user
cookies[:userdata] = { :value => user, :expires => 8.hours.from_now.utc }
else
#current_user = nil
cookies.delete(:userdata)
end
end
def current_user
binding.pry
#current_user ||= (cookies[:userdata] ? cookies[:userdata] : nil)
end
end
The getter method is hit correctly every time but the setter is never getting hit. Any ideas as how to fix this thanks.
When you are assigning to current_user it's treating it as a local variable. To solve that simply assign to self.current_user instead. The getter doesn't need that because there is no local variable named that so ruby looks for a method and uses that. If you reference the getter as self.current_user that would also work.
For example change:
current_user = response["User"]
to:
self.current_user = response["User"]
Include SessionsHelper in your SessionsController in order to access SessionHelper methods within SessionsController.
Code will work fine without any modification i.e., you would be able to access current_user and current_user= directly.
class SessionsController < ApplicationController
include SessionsHelper ## Just add this
..
end

Resources