Why is current_user giving me an error? - ruby-on-rails

In my create method in the Videos controller, this line works:
#video = Video.new(params[:video])
However, I want to assign the video to the user, so I use this line which gives me an error:
#video = current_user.videos.new(params[:video])
This is the error:
NoMethodError in VideosController#create
undefined method `videos' for nil:NilClass
I have this in my User model:
has_many :videos
And this in my Video model:
belongs_to :user
This is in my application_controller file:
def current_user
return unless session[:user_id]
#current_user ||= User.find_by_id(session[:user_id])
end
# Make current_user available in templates as a helper
helper_method :current_user
How do I fix this error? Let me know if I should post anymore code.

Is this error only happening when the user is not logged or there's no session[:user_id]?
When not logged in:
#video = current_user.videos.new(params[:video])
...would be...
#video = nil.videos.new(params[:video])
which would give you that exact NoMethodError

Related

Rails current_user nil

I have a controller, in this controller #current user is OK in show, new, create, but doesn't work in def _params, for example, #current_user.role:
undefined method `role' for nil:NilClass.
Thanks.
def company_params
if #current_user.role.name != 'admin'
params[:company_id] = #current_user.company.id
end
params.require(:company).permit(.........)
end
ERROR: undefined method `role' for nil:NilClass
#current_user is defined in a filter at the begginng but just for the defined actions. The company params doesn't seem to be included in the list. Try adding it.
before_action :set_current_user, only: [:balbalba, :company_params] #might look different

Ruby on Rails - showing posts of signed in user

I'm just starting out with Rails and I got stuck with displaying properties that only belongs to signed in user.
I have a user, post model with the following associations
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
end
class Post < ActiveRecord::Base
belongs_to :user
end
and on post controller I'm trying to access current user's posts with session helper method called current_user but it complains that posts is undefined
def index
#posts = current_user.posts
end
This is the helper method
def current_user
remember_token = User.digest(cookies[:remember_token])
#current_user ||= User.find_by(remember_token: remember_token)
end
Can someone please shed some light on it?
Error Message
NoMethodError in PostsController#index
undefined method `posts' for nil:NilClass
It's is not the method posts is undefined. Your current_user object is nil and that means the user with this remember_token is not found. If you never want a undefined method posts for nil:NilClass type in current_user.try(:posts) so that if the user is logged out they won't see the error. Or create this method in your application controller.
application_controller.rb
private
def is_logged_in?
current_user.present?
end
And call this method in the before_filter section of your controller.
Anyways why not use devise gem for your authentication process. It's is very reliable and comes with the current_user and authenticate_user! methods defined out of the box
It says that the value your current_user is nil, and nil does not have method posts.
Check your user's remember token, and print the parameter you feed to find_by.
Eeeer... is it complaining on the view or the controller? tell us exactly what it complains about (copy paste the result). Maybe use #posts in your view instead of posts (ofcourse posts is undefined, #posts is defined).

add a column value before saving item to database

Say user submits a form (creates new item in his account).
Before it goes to database - I want to do this:
params[:user] => current_user.id
# make a note of who is the owner of the item
# without people seing this or being able to change it themselves
# and only after that to save it to database
What's the best way to do it?
All I see in controller is this:
def create
#item = Item.new(params[:item])
...
end
And I'm not sure how to change values under params[:item]
(current_user.id is Devise variable)
Tried to do this:
class Item < ActiveRecord::Base
before_save :set_user
protected
def set_user
self.user = current_user.id unless self.user
end
end
And got an error:
undefined local variable or method `current_user'
It should be as simple as:
def create
#item = Item.new(params[:item])
#item.user = current_user
#...
end
You're getting an undefined local variable or method current_user error as current_user is not available in the model context, only controller and views.

Why my rails associations don't work in controller but they work in views?

I've got User has_one Shop & Shop has_many Branches.
When I do this:
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#shop = #user.shop
#branches = #shop.branches
end
...
The #user & #shop instance variable works in view, but #branches gives me the error:
undefined method `branches' for nil:NilClass
Application Trace | Framework Trace | Full Trace
app/controllers/users_controller.rb:13:in `show'
However, if I discard #branches in the controller:
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#shop = #user.shop
end
...
....and use this in the view:
#shop.branches
....it works! It's kinda tiring to use #shop.branches in the view all the time, so I prefer to just use #branches.
The message indicates that #shop is nil in the controller. If with the same request it works in the view, it means that certainly #shop has been set somewhere else after the controller.

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