Ruby on Rails 3.2
My SessionsHelper is working for one of my models but not the other. I cannot figure out the problem. I get his error:
NameError (undefined local variable or method `distributor' for #<DistributorsController:0x00000005357c58>):
app/helpers/sessions_helper.rb:55:in `current_distributor'
app/helpers/sessions_helper.rb:59:in `current_distributor?'
app/controllers/distributors_controller.rb:138:in `correct_distributor'
These are all defined in my helper. My ApplicationController has include SessionsHelper .What is the problem?
This is part of my helper:
def sign_in_distributor(distributor)
cookies[:remember_token] = distributor.remember_token
self.current_distributor = distributor
end
def signed_in_distributor?
!current_distributor.nil?
end
def current_distributor=(distributor)
#current_distributor = distributor
end
def current_distributor
#current_distributor ||= distributor.find_by_remember_token(cookies[:remember_token])
end
def current_distributor?(distributor)
distributor == current_distributor
end
def sign_out_distributor
self.current_distributor = nil
cookies.delete(:remember_token)
end
def admin_distributor
redirect_to(current_distributor) unless current_distributor.admin?
end
def admin_distributor?
current_distributor.admin?
end
This is my controller:
class DistributorsController < ApplicationController
before_filter :signed_in_grandstreamer, only: [:edit, :update, :show, :index]
before_filter :correct_distributor, only: [:edit, :update, :show, :change_password]
before_filter :admin_distributor, only: [:index, :new, :edit, :destroy]
def index
#distributors = Distributor.paginate(page: params[:page])
redirect_to root_url
end
def new
if signed_in_distributor?
redirect_to distributor_path(current_distributor)
elsif signed_in_grandstreamer?
redirect_to grandstreamer_path(current_grandstreamer)
else
#distributor = Distributor.new
end
end
def show
##distributor = Distributor.find(params[:id])
end
...skipping some...
private
def signed_in_grandstreamer
unless signed_in_grandstreamer?
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in_grandstreamer?
end
end
def signed_in_distributor
unless signed_in_distributor?
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in_distributor?
end
end
def correct_distributor
#distributor = Distributor.find(params[:id])
##user = User.find(current_user.id)
#checkuser = Distributor.find(params[:id])
redirect_to(current_distributor) unless current_distributor?(#checkuser) || admin_distributor?
end
end
I think you need to change this helper:
def current_distributor
#current_distributor ||= distributor.find_by_remember_token(cookies[:remember_token])
end
To:
def current_distributor
#current_distributor ||= Distributor.find_by_remember_token(cookies[:remember_token])
end
Using CamelCase for class name.
Try changing
distributor.find_by_remember_token(cookies[:remember_token])
To this
Distributor.find_by_remember_token(cookies[:remember_token])
Related
Hi i got error with impressionist gem. i use Rails 5.2.4.4
i did these steps :
gem 'impressionist'
then bundle install
then rails g impressionist and bundle install
Then next step :
in my blogs_controllers
class BlogsController < ApplicationController
before_action :authorize_admin, only: [:new, :edit, :create, :update]
before_action :set_blog, only: [:show, :edit, :update, :destroy]
impressionist :actions => [:show, :index]
def index
#categories = Category.all
cate = params[:cate]
if !cate.nil?
#blogs = Blog.where(:category_id => cate)
else
#blogs = Blog.all
end
end
def show
impressionist(#blog)
end
def new
#blog = Blog.new
end
def create
#blog = Blog.new(blog_params)
if #blog.save
redirect_to blog_path(#blog), notice: "Successfully Created"
else
render :new
end
end
def edit
end
def update
#blog.slug = nil
if #blog.update(blog_params)
redirect_to blog_path(#blog), notice: "Successfully Update"
else
render 'edit'
end
end
def destroy
#blog.destroy
redirect_to blogs_path
end
private
def set_blog
#blog = Blog.find(params[:id])
end
def blog_params
params.require(:blog).permit(:title, :body, :image, :category_id)
end
def authorize_admin
return unless !current_user.admin?
redirect_to root_path
end
end
in blog model
is_impressionable
in blog show
<%= #blog.impressionist_count(:filter=>:ip_address) %>
And i got this error :
NameError in BlogsController#show
uninitialized constant ActiveSupport::ParameterFilter
Extracted source (around line #80):
# If the constant was actually loaded, something else went wrong?
raise(e) if from_mod.const_defined?(const_name)
CoreExt::ActiveSupport.without_bootsnap_cache { super }
end
# Signature has changed a few times over the years; easiest to not
I have a user and article model where a user can have many models, and have restricted the delete function to user or admin. yet when i attempt to destroy the article, i get the following error:
undefined method `user' for nil:NilClass
and its pointing to this private function in my articles controller:
def require_same_user
if current_user != #article.user and !current_user.admin?
flash[:danger] = "You can only edit or delete your own articles"
redirect_to root_path
end
end
this is my whole controller file:
class ArticlesController < ApplicationController
before_action :set_article, only: [:edit, :update, :show]
before_action :require_user, except: [:index, :show]
before_action :require_same_user, only: [:edit, :update, :destroy]
def index
#articles = Article.paginate(page: params[:page], per_page: 5)
end
def show
end
def new
#article = Article.new
end
def edit
end
def update
#article.update(article_params)
if #article.save
flash[:success] = "Article successfully updated!"
redirect_to article_path(#article)
else
flash[:danger] = "Sorry, try again..."
render :edit
end
end
def create
#article = Article.new(article_params)
#article.user = current_user
if #article.save
flash[:success] = "New article created"
redirect_to articles_path
else
flash[:danger] = "Sorry, invalid values"
render :new
end
end
def destroy
#article = Article.find(params[:id])
#article.destroy
flash[:success] = "Article deleted"
redirect_to articles_path
end
private
def article_params
params.require(:article).permit(:name, :title, :description)
end
def set_article
#article = Article.find(params[:id])
end
def require_same_user
if current_user != #article.user and !current_user.admin?
flash[:danger] = "You can only edit or delete your own articles"
redirect_to root_path
end
end
end
the articles and users exist in db so what could this be? thanks in advance
You're setting the article using the set_article function, but in the case of the require_same_user function, it doesn't know what's the value of #article; so in that case, the value is nil, as it's not in the scope, nor figure as an instance variable created before.
def require_same_user
# Here there's no #article, so it's evaluated as nil,
# and nil doesn't have a method user.
if current_user != #article.user ...
...
One approach could be to set the set_article also to be executed before the require_same_user does it.
before_action :set_article, only: %i[edit update show require_same_user]
You could also divide your code in smaller pieces to be used back again whenever you need it:
def require_same_user
redirect_to_root_path unless article_owner? && admin?
end
def redirect_to_root_path
flash[:danger] = 'You can only edit or delete your own articles'
redirect_to root_path
end
def admin?
current_user.admin?
end
def article_owner?
current_user == #article.user
end
Make sure set_article runs before destroy action.
In your controller:
before_action :set_article, only: [:edit, :update, :show, :destroy]
I've been following Rails Tutorial from Michael Hartl, https://www.railstutorial.org/book/updating_and_deleting_users.
I am having an error to pass one of the action level tests for admin access control test.
The test failed is as follows:
def setup
#user = users(:jessie) #admin
#other_user = users(:brenda) #non_admin
end
test "should redirect destroy when logged in as a non-admin" do
log_in_as(#other_user)
assert_no_difference 'User.count' do
delete user_path(#user)
end
assert_redirected_to root_url
end
The error that the terminal gives me is :
FAIL["test_should_redirect_destroy_when_logged_in_as_a_non-admin", UsersControllerTest, 1.6799899999750778]
test_should_redirect_destroy_when_logged_in_as_a_non-admin#UsersControllerTest (1.68s)
Expected response to be a redirect to root_url but was a redirect to login_url.
Expected root_url to be === login_url.
test/controllers/users_controller_test.rb:65:in `block in '
My users_controller.rb file is:
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def show
#user=User.find(params[:id])
end
def new
#user= User.new
end
def create
#user=User.new(user_params)
if #user.save
log_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def index
#users = User.paginate(page: params[:page])
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
#Confirms a logged_in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the current user.
def correct_user
#user = User.find(params[:id])
recirect_to(root_url) unless current_user?(#user)
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Confirms an admin user
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
As I've been following the tutorial strictly and I am still very new to ruby on rails, it's very hard for me to identify where went wrong. I've been googling for solutions for a few hours, but in vain. Any help would be greatly appreciated. Thank you :)
I am currently in the process of learning Ruby on Rails through Michael Hartl's Rails Tutorial (Chapter 12). I am suddenly getting the below error.
UsersControllerTest#test_should_redirect_destroy_when_not_logged_in:
NoMethodError: undefined method admin?' for nil:NilClass
app/controllers/users_controller.rb:92:inadmin_user'
test/controllers/users_controller_test.rb:48:in block (2 levels) in <class:UsersControllerTest>'
test/controllers/users_controller_test.rb:47:inblock in '
Here is my test code:
test "should redirect destroy when not logged in" do
assert_no_difference 'User.count' do
delete :destroy, id: #user
end
assert_redirected_to login_url
end
And the rest of my code:
class UsersController < ApplicationController
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
:following, :followers]
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
def index
#users = User.paginate(page: params[:page])
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def following
#title = "Following"
#user = User.find(params[:id])
#users = #user.following.paginate(page: params[:page])
render 'show_follow'
end
def followers
#title = "Followers"
#user = User.find(params[:id])
#users = #user.followers.paginate(page: params[:page])
render 'show_follow'
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Before filters
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
Can someone please have a look and tell me where I am going wrong? The code has basically been copied from the tutorial so I'm at a loss.
Thanks.
I had this same error in the Hartl tutorial. The problem was a missed :destroy action in listing 9.53 in users_controller.rb. Tests were back to green once I found that missing bit.
That said, it would be great if someone could explain precisely why this is the case.
The correct code:
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
Change admin_user method like this:-
def admin_user
redirect_to(root_url) unless current_user.present? && current_user.admin?
end
This will check first that current_user is present or not then check second condition(current_user.admin?). If current_user.present? will false then it will not check second condition.
You need to update your admin_user method to check if user is even logged in.
# Confirms an admin user.
def admin_user
redirect_to(root_url) if current_user.nil? || !current_user.admin?
end
I'm using Rails 3.2 and Authlogic. I have the following code:
class ApplicationController < ActionController::Base
private
def store_location
session[:return_to] = request.url
end
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
end
class UserSessionsController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => :destroy
def new
#user_session = UserSession.new
#header_title = "Login"
end
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:success] = "Login successful!"
redirect_back_or_default root_url
else
render 'new'
end
end
def destroy
current_user_session.destroy
flash[:success] = "Logout successful!"
redirect_back_or_default root_url
end
end
This code is quite generic. When we use the before_filter:
before_filter :require_user, :only => [:new, :edit, :update, :create]
It will automatically store_location and redirect us back to the proper page. However, how do I do this:
I'm in posts/1 which doesn't require_user.
I click the login link on my top navigation bar.
It shows the login page.
Once login, I will be redirected back to posts/1 instead of the root_url.
Place a direct call to store_location in the sessions controller new action.
# user_sessions_controller.rb
def new
store_location if session[:return_to].blank?
#user_session = UserSession.new
#header_title = "Login"
end
This will first check for an existing return_to pair in the sessions hash. You don't want to overwrite it in case, for example, a user is redirected to the new action because of a bad password.
This will also skip store_location if it was already called from require_user.
After a successful redirect, you have to delete the return_to pair from the sessions hash; setting it to nil is not enough:
# application_controller.rb
def redirect_back_or_default(default)
redirect_to(session.delete(:return_to) || default)
end
I added a store_referrer_location to make it work:
# application_controller.rb
class ApplicationController < ActionController::Base
private
def store_referrer_location
session[:return_to] = request.referrer
end
end
# user_sessions_controller.rb
class UserSessionsController < ApplicationController
def new
store_referrer_location if session[:return_to].blank?
#user_session = UserSession.new
#header_title = "Login"
end
...
def destroy
store_referrer_location if session[:return_to].blank?
current_user_session.destroy
flash[:success] = "Logout successful!"
redirect_back_or_default root_url
end
end