undefined method `current_user' for #<Teacher:0x00000004fcac48> - ruby-on-rails

I am using Devise gem in my Rails project. The reason I use Devise is because I want just logged in user can rate their teachers. Now, I get this error in my ratings_controller.rb although I already added user_id into my ratings and teachers table.
undefined method `current_user' for Teacher:0x00000004fcac48
#rating = #teacher.current_user.ratings.build
Here is my ratings_controller.rb:
class RatingsController < ApplicationController
def new
get_teacher
#rating = #teacher.current_user.ratings.build
end
def create
get_teacher
#rating = #teacher.current_user.ratings.create(rating_params)
if #rating.save
redirect_to school_teacher_path(#teacher.school, #teacher)
else
render 'new'
end
end
def destroy
get_teacher
#rating = #teacher.ratings.find(params[:id])
#rating.destroy
redirect_to school_teacher_path(#teacher.school, #teacher)
end
def get_teacher
#teacher = Teacher.find(params[:teacher_id])
end
private
def rating_params
params.require(:rating).permit(:easiness, :helpfulness, :clarity, :comment,
:teacher_id, :school_id)
end
end
rating.rb:
class Rating < ActiveRecord::Base
belongs_to :teacher
belongs_to :user
end
teacher.rb:
class Teacher < ActiveRecord::Base
belongs_to :school
has_many :ratings, dependent: :destroy
has_many :users
def name
"#{firstName} #{middleName} #{lastName}"
end
def to_s
name
end
end
user.rb:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :ratings
has_many :teachers
end

current_user is a controller helper, it's not a instance method of model.
you can add before_action :authenticate_user! in controller to make sure only logged in user can rate

You can change several code here. Before fixing your code, I suggest you to user before_action to make DRY code.
class RatingsController < ApplicationController
before_action :authenticate_user!
before_action :get_teacher
# your code #
private
def get_teacher
#teacher = Teacher.find(params[:teacher_id])
end
def rating_params
params.require(:rating).permit(:easiness, :helpfulness, :clarity, :comment, :teacher_id, :school_id)
end
end
Then, add before_action :authenticate_user! above before_action :get_teacher so you can get current_user in each method.
Finally, you have to fix your new and create method into this:
def new
#rating = current_user.ratings.build
end
def create
#rating = current_user.ratings.create(rating_params)
if #rating.save
redirect_to school_teacher_path(#teacher.school, #teacher)
else
render 'new'
end
end
You do not need to #teacher.current_user.ratings.create(rating_params) to get teacher_id because you have teacher_id in your rating_params. I hope this help you.

You need to build rating object for user like this:-
#rating = current_user.ratings.build

Related

Getting error: undefined method `call' for nil:NilClass

I get such an error when try to create a new bound essence.
NoMethodError in AccountsController#create undefined method `call' for nil:NilClass
I have 2 bound models:
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable
has_one :account, dependent: :destroy
end
class Account < ApplicationRecord
belongs_to :user, optional: true
end
Account controller look like:
class AccountsController < ApplicationController
before_action :authenticate_user!
def new
#user = User.find_by(id: current_user.id)
#account = #user.build_account
end
def create
#user = User.find_by(id: current_user.id)
#account = #user.build_account(account_params)
if #account.save
flash[:success] = 'Account saved successfully'
redirect_to #account
else
render action: "new"
end
private
def account_params
params.require(:account).permit(:gender, :date_birthday, :description, :location, :nationality, :interests, :first_name, :last_name)
end
end
I tried to write #user.account.new(..), but it didn't help. I guess the error can appear because of I have an any errror in routes. But I checked it many times and found nothing.
Why do I get this error? I will be glad for your help!

How can a user report another user?

I have a User model. A user can be an employer or a student. So there is an employer model and a student model. They both belong to user. Only employers can view student profiles. So if there is something wrong with the profile, the employer should be able to report the profile. I was thinking of having a "report" button on the profile which only the employers can see. Then when they click on it, the admin (me) gets an email with the url or the id of the student.
Right now, the student profile url looks like www.mywebsite.com/students/john-big. How can the report button be setup so the whole URL or the user-id (John-big) gets emailed to me.
The mailer is set up already because I set it up in a way where I get an email every time a user signs up. I can use the same logic to email myself, but grabbing the ID or url is the problem. What is the best way to do it?
Userinfo controller (userinfo =student):
class UserinfosController < ApplicationController
before_action :find_userinfo, only: [:show, :edit, :update, :destroy, :log_impression]
before_action :authenticate_user!
def index
end
def show
end
def new
#userinformation = current_user.build_userinfo
end
def create
#userinformation = current_user.build_userinfo(userinfo_params)
if #userinformation.save
redirect_to userinfo_path(#userinformation)
else
render 'new'
end
end
def edit
end
def update
if #userinformation.update(userinfo_params)
redirect_to userinfo_path(#userinformation)
else
render 'edit'
end
end
def destroy
#userinformation.destroy
redirect_to root_path
end
private
def userinfo_params
params.require(:userinfo).permit(:name, :email, :college, :gpa, :major)
end
def find_userinfo
#userinformation = Userinfo.friendly.find(params[:id])
end
end
Employer controller:
class EmployersController < ApplicationController
before_action :find_employer, only: [:show, :edit, :update, :destroy]
def index
end
def show
end
def new
#employer = current_user.build_employer
end
def create
#employer = current_user.build_employer(employer_params)
if #employer.save
redirect_to userinfos_path
else
render 'new'
end
end
def edit
end
def update
if #employer.update(employer_params)
redirect_to employer_path(#employer)
else
render 'edit'
end
end
def destroy
#employer.destroy
redirect_to root_path
end
private
def employer_params
params.require(:employer).permit(:paid, :name, :company, :position, :number, :email, :emp_img)
end
def find_employer
#employer = Employer.friendly.find(params[:id])
end
end
User model:
class User < ActiveRecord::Base
has_one :userinfo
has_one :employer
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
acts_as_messageable
after_create :welcome_send
def welcome_send
WelcomeMailer.welcome_send(self).deliver_now
end
end
Please let me know if you guys need more information.
I would use request.url() to get the URL of your view (the student profile url).
Try adding this to you view to get a feeling of it:
<%= debug("request.url: #{request.url()}") if Rails.env.development? %>
I hope this helps.

Building a Q&A app in rails, I am a bit unsure about how to send questions to a specific user

As the title suggests, I am building a Q&A application (Like ask.fm) in Ruby on Rails, and I am having some trouble with sending the question to a specific user.
I have 3 models, a User model (from Devise), A Question model with this attribute: content:text and a Answer model with this attribute: content:text
Here are their models
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
class Question < ActiveRecord::Base
has_one :answer
belongs_to :user
end
class User < ActiveRecord::Base
has_many :questions
has_many :answers
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
And here are the migrations that I created
This one adds a user_id to the question (So I can check which user sent the question, btw this works fine)
class AddUserIdToQuestion < ActiveRecord::Migration
def change
add_column :questions, :user_id, :integer
end
end
Here I tried to add a receiver (the user that would get the question) but I wont work, when I create a Question It will be equal to 'nil', when I check it out in the rails console (Check the controller to see what I did)
class AddReceiverToQuestion < ActiveRecord::Migration
def change
add_column :questions, :receiver, :integer
end
end
Here is the question controller
class QuestionsController < ApplicationController
def new
#question = Question.new
end
def create
#question = Question.new(question_params)
#question.user_id = current_user.id
if #question.save
redirect_to root_path
else
render 'new'
end
end
private
def question_params
params.require(:question).permit(:content, :user_id)
end
end
I also have a user profile page where I have a form show up, here is the controller for that one
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#user_questions = #user.questions
#question = Question.new
end
def create
#user = User.find(params[:id])
#question = Question.new(question_params)
#question.receiver = #user.id #This does not work
if #question.save
redirect_to root_path
else
render 'new'
end
end
private
def question_params
params.require(:question).permit(:content, :user_id, :receiver)
end
end
I really hope some of you know what I could do here, thank you :)

Linking a user id to a profile model - Ruby on Rails

I have a basic rails app with devise set up and a profile model generated with scaffolding. The Profile model is where the user will add detailed information about themselves after they sign up. Everything is working fine except for one issue: after the user creates a profile, the new profile is created however it is not linked to that user id. I have generated the migration to add user_id to profile. How can I make the profile that the user creates get saved and linked to the currently signed in user?
here is my current code:
Profiles controller:
class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :set_profile, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#profiles = Profile.all
respond_with(#profiles)
end
def show
#profile = Profile.find(params[:id])
respond_with(#profile)
end
def new
#profile = Profile.new
respond_with(#profile)
end
def edit
end
def create
#profile = Profile.new(profile_params)
#profile.save
respond_with(#profile)
end
def update
#profile.update(profile_params)
respond_with(#profile)
end
def destroy
#profile.destroy
respond_with(#profile)
end
private
def set_profile
#profile = Profile.find(params[:id])
end
def profile_params
params.require(:profile).permit(:name, :civil, :email, :level, :employment_date, :mobile, :folder, :title, :internal, :nationality, :vacation, :work_email, :experience)
end
end
Profile model:
class Profile < ActiveRecord::Base
belongs_to :user
validates_associated :user
end
User model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :profile
end
As long as you use devise, it should be as simple as:
class ProfilesController < ApplicationController
def create
#profile = Profile.new(profile_params)
#profile.user_id = current_user.id
#profile.save
respond_with(#profile)
end
end
Devise creates that helper method for you. Check its docs page.

rails rotum object belonging to the user object

I have 2 controllers User and Rota. I want the user to be able to create their own Rota but only be able to edit, show and destroy their own. I need to be able to code so that my rotum object belongs to the user object.
ROTA CONTROLLER:
class RotaController < ApplicationController
respond_to :html, :xml, :json
before_action :set_rotum, only: [:show, :edit, :update, :destroy]
def edit
#rotum = #user.rota.find params[:id]
end
def index
#rota = Rotum.all
respond_with(#rota)
end
def show
respond_with(#rotum)
end
def new
#rotum = Rotum.new
respond_with(#rotum)
end
def edit
end
def create
#rotum = Rotum.new(rotum_params)
#rotum.save
respond_with(#rotum)
end
def update
#rotum.update(rotum_params)
respond_with(#rotum)
end
def destroy
#rotum.destroy
respond_with(#rotum)
end
private
def set_rotum
#rotum = current_user.rotums.find(params[:id])
if #rotum.nil?
render :html => "Not authorized", :status => 401
end
end
def rotum_params
params.require(:rotum).permit(:name, :email, :mobile, :category)
end
end
USER CONTROLLER
class UsersController < ApplicationController
before_filter :authenticate_user!
after_action :verify_authorized
def index
#users = User.all
authorize User
end
def show
#user = User.find(params[:id])
authorize #user
end
def update
#user = User.find(params[:id])
authorize #user
if #user.update_attributes(secure_params)
redirect_to users_path, :notice => "User updated."
else
redirect_to users_path, :alert => "Unable to update user."
end
end
def destroy
user = User.find(params[:id])
authorize user
user.destroy
redirect_to users_path, :notice => "User deleted."
end
def edit
#rotum = #user.rota.find params[:id]
end
private
def secure_params
params.require(:user).permit(:role)
end
end
So far my rota allows anyone to create, show, edit and destroy the rota on the rotas page. I only want the user to be able to edit only THEIR OWN rota that they created. For that I have been told tell the rota object to belong to the user object. How can I do this in my controllers or models.
USER MODEL
class User < ActiveRecord::Base
has_many :rota, dependent: :destroy
enum role: [:user, :vip, :admin]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :user
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
ROTUM MODEL
class Rotum < ActiveRecord::Base
belongs_to :user
end
I get the error:
NoMethodError at /rota/15
undefined method `rotums' for #
You are not showing your models, so I'm assuming that you have a has_many relationship
class User < ActiveRecord::Base
has_many :rota, dependent: :destroy
end
class Rotum < ActiveRecord::Base
belongs_to :user
end
then in your controller you can use the following:
class UsersController < ApplicationController
....
def edit
#rotum = #user.rota.find params[:id]
end
Note that this will raise an ActiveRecord::RecordNotFound exception if a user is triying to edit a rotum that does not belong to him.
You can avoid that problem with the following:
class UsersController < ApplicationController
....
def edit
#rotum = #user.rota.find_by id: params[:id] # returns nil in case the record does not exist or does not belong to #user
redirect_to "somewhere", alert: 'You cannot edit this element' if #rotum.blank?
end

Resources