Ruby. Variable permission - ruby-on-rails

I have a problem to access to variable in other method in this class. Here is my example:
class CustomersController < ApplicationController
def login
if params[:login].present? && params[:password].present?
**#cust_model** = Customers.new
redirect_to(:action => 'client_dashboard')
end
end
def client_dashboard
#cust_dashboard = **#cust_model**.dashboard(1)
end
end
My error is: undefined method dashboard

After redirection from login, #cust_model will naturally be nil in client_dashboard action. It can't be inherited from login action like this, and that's why dashboard is undefined for that Customer
Since you have #cust_model = Customer.new, you can then sufficiently use #cust_dashboard = Customer.new.dashboard(1), if this is what you intended to (according to your given code).
Cheers.

Related

Pundit: undefined method `authorize'

I am trying to use Pundit to authenticate access to some static views that require no database interaction:
class StaticController < ApplicationController
include Pundit
authorize :splash, :home?
def home end
end
Below is my static policy. The home? policy always returns true, so I should be able to access the home view.
class StaticPolicy < Struct.new(:user, :static)
def initialize(user, resource)
#user = user
#resource = resource
end
def home?
true
end
end
Instead I get this:
undefined method `authorize' for StaticController:Class
Pundit works perfectly if I'm authorizing a model:
def forums_index
#forums = Forum.all
authorize #forums
end
However, if I try to use the authorize method outside of an action that doesn't make use of a model I get:
undefined method `authorize' for StaticController:Class
Well, AFAIK you'll always have to authorize against either an object or a class, while CanCan already "load_and_authorize_resource", when using Pundit you already know that you have to load and authorize something yourself (sorry if I'm being too obvious here).
That said and considering that your view doesn't have DB interation, it seems to me that the best solution for your case is make some custom authorization against your user, something like
class StaticPolicy < Struct.new(:user, :static)
def initialize(user, resource)
#user = user
#resource = resource
end
def home?
authorize #user, :admin # or suppress the second parameter and let the Policy use the 'home?' method
true
end
end
and in your UserPolicy something like
class UserPolicy < ApplicationPolicy
def admin # or def home?, it's up to you
user.admin?
end
end
I didn't test it, but that's the main idea, does it make any sense? Is it clear?
Please give it a try and post any impressions, hope it helps :)

Sessions and rails: Sessions a undefined variable/method?

So, I have this error:
undefined local variable or method session for ApplicationController:Class
So what I am guessing is rails, there is no "session" variable until it is set, right?
Or am I doing something wrong. This is the code using it:
class ApplicationController < ActionController::Base
# Pre vent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
#account = User.find session[:userid]
end
I set it in the login page. Would there be a way to only execute is it isn't nil, or would that not work as it is truly undefined? Am I checking sessions right?
The code for setting sessions:
class SessionsController < ApplicationController
def login
end
def login_attempt
authuser = User.auth(params[:name], params[:password])
if authuser
session[:userid] = authuser.id
flash[:notice] = "We logged you in, #{authuser.name}!"
else
flash[:notice] = "INVALID USERNAME/PASSWORD!"
end
end
end
So... Any ideas what this error message even means. I see there was a question like this, but that isn't the same, according to my testing (Or is it?)
session method does exist, but it's on instance only, not on class level.
In your code, you defined #account at class level. That is wrong.
Do it in instance method instead:
def foo
#account = User.find session[:something]
end

I defined a method but still getting an error 'rails undefined method'

I'm doing an authentication application. I have this code
class UsersController < ApplicationController
def new
#user = User.new
#title = "User Sign Up"
end
def create
#user = User.new(params[:user])
sign_in_check #user
if #user.save
#flash[:status] = true
#flash[:alert] = "You have successfully signed up!!"
#sign_in_check #user
redirect_to root_path, :flash => { :success => "Welcome to the Bakeshop"}
else
#title = "User Sign Up"
render 'new'
end
end
end
This is a simple sign-up code, and whenever I try and sign up, rails returns an error:
undefined method `sign_in_check' for #<UsersController:0x68c0a90>
but I defined a method sign_in_check in my Users_helper.rb:
module UsersHelper
def sign_in_check(user)
#some stuff to enable session
end
end
Does anyone have an idea why this is happening, and how to fix it?
The reason is your method is a helper. Helpers will be available in views with matching name by default, but not open to controllers without setting.
Two ways to fix:
Allow this helper in UsersController
class UsersController < ApplicationController
helper :user #This will expose UsersHelper module to UsersController
Instead, put this method into ApplicationController. I would prefer this due to the method's nature.
Include your UserHelper in your UserController as follows and you should be able to use any methods defined within the helper.
class UsersController < ApplicationController
include UsersHelper
...
end
This is usually put in the application controller
class ApplicationController < ActionController::Base
def sign_in_check(user)
#some stuff to enable session
end
end
Helpers are used for views. If you want to use it in both - you can do that, but that doesn't sound like what you're looking for here.
just include your helper module in your controller
class UsersController < ApplicationController
helper :user
...
end
Thanks

What does self do in ruby on rails?

I'm on railcasts just practicing some rails and have come across something I'm trying to understand.
I didn't get what the "self" on the authenticate method was doing. So I deleted it and tested the login of my app to see if it would show an error and it did:
error:
**NoMethodError in SessionsController#create
undefined method `authenticate' for #<Class:0x00000102cb9000**>
I would really appreciate if someone could explain exactly what that "Self" is doing. I was trying to figure out exactly what was going on but can't get my head around it.
Method is defined in model and called in sessions_controller..
I've been continuously deleting my app and starting from scratch to get the hang of it and many things make sense to me each time i start again but I'm stuck at "self".
I'm just the type of person who likes to understand why something works.
controller:
def create
user = User.authenticate(params[:email], params[:password])
if user
session[:user_id] = user.id
redirect_to root_path, :notice => "Logged In"
else
flash.now.alert = "Invalid credentials"
render "new"
end
end
model:
def self.authenticate(email, password)
user = find_by_email(email)
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
This is a basic ruby question. In this case, self is used to define a class method.
class MyClass
def instance_method
puts "instance method"
end
def self.class_method
puts "class method"
end
end
Which are used like this:
instance = MyClass.new
instance.instance_method
Or:
MyClass.class_method
Hope that clears things up a little bit. Also refer to: http://railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/
self defines a method of the class instead of the instance of the class. So with def self.authenticate you can do the following:
u = User.authenticate('email#domain.com','p#ss')
Instead of doing…
u = User.new
u.authenticate('email#domain.com','p#ss')
That way, you don't have to create an instance of user to authenticate one.
For the sake of completion and to thwart future headaches, I'd like to also point out that the two are equivalent:
class User
def self.authenticate
end
end
class User
def User.authenticate
end
end
Matter of preference.
class User
def self.xxx
end
end
is one way of defining class method while
class User
def xxx
end
end
will define an instance method.
If you remove the self. from the def, you will get a method not found error when you do
User.authenticate
because you are trying to call a method on a class rather than an instance of the class. To use an instance method, you need an instance of a class.

Rails - session request is nil error

I have a method that I want to execute some search logic, and then save a Search object that has the searched string and user id of the person who did the search.
The search/save logic seems to be working fine otherwise, but when I try to get the current user (using a method from the application controller) it throws a runtime error that has to do with the session:
ActionController::Metal#session delegated to #_request.session, but #_request is nil: #<SearchController:0x1038e32e0 #action_has_layout=true, #view_context_class=nil, #_status=200, #_headers={"Content-Type"=>"text/html"}>
Here's the method in the search controller:
class SearchController < ApplicationController
...
def factualsearch(search)
if search
searchquery = Search.new
# this causes the error
if current_user
searchquery.user = current_user
end
searchquery.search_string = search
searchquery.save
...
end
#results
end
end
Here's the current_user method I'm trying to call from my application controller:
def current_user
return unless session[:user_id]
#current_user ||= User.find_by_id(session[:user_id])
end
helper_method :current_user
Here's the pages controller where I'm calling the method:
class PagesController < ApplicationController
...
def search
searchcontrol = SearchController.new
#results = searchcontrol.factualsearch(params[:search])
end
...
end
Not exactly a direct way to fix this problem, but I was able to get around it by have the function accept the user in addition to the search query, rather than trying to call the current_user method from inside it. The class that calls the action can access the current_user method just fine.

Resources