I am not sure that it is even related but since i added devise i am getting a no method error which reads as follows. undefined method `posts' for nil:NilClass
This is specifically directed at the following line of code.
#post = current_user.posts.build
I am rather stuck here as i have checked all the obvious and unless i remove the code so it reads
#post = Post.new
I am otherwise unable to add new posts. I have added the full code below.
Posts Controller
class PostsController < ApplicationController
before_action :find_post, only: [:show, :edit, :update, :destroy]
def index
#posts = Post.all.order("created_at DESC")
end
def show
end
def new
#post = current_user.posts.build
end
def create
#post = current_user.posts.build(post_params)
if #post.save
redirect_to #post
else
render 'new'
end
end
def edit
end
def update
if #post.update(post_params)
redirect_to #post
else
render 'edit'
end
end
def destroy
#post.destroy
redirect_to root_path
end
private
def find_post
#post = Post.find(params[:id])
end
def post_params
params.require(:post).permit(:title, :content)
end
end
Post model`
class Post < ActiveRecord::Base
belongs_to :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_many :posts
end
new html haml
%h1 New Post
= render 'form'
The code looks ok...
But what happens if there is no user signed in?
try add
before_action :authenticate_user!
or ask
user_signed_in?
before you try to access the logged in user.
Need to see your how you have integrated your devise. But yes, maybe your not signed in that's why the nil error.
Related
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.
I'm new to Rails and I'm stuck at something really silly. I was trying to make an app where users can post pinterest-like pins, so I went with user has_many: pins and pin belongs_to: user. Here's the codes from a few files just to give you an idea of what state I'm in right now:
app/models/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 :pins
end
app/models/pin.rb
class Pin < ActiveRecord::Base
belongs_to :user
end
pins_controller.rb
class PinsController < ApplicationController
before_action :find_pin, only: [:show, :edit, :update, :destroy]
def index
#pins = Pin.all.order("created_at DESC")
end
def show
end
def new
#pin = current_user.pins.build
end
def create
#pin = current_user.pins.build(pin_params)
if #pin.save
redirect_to #pin, notice: "Successfully created new Pin"
else
render 'new'
end
end
def edit
end
def update
if #pin.update(pin_params)
redirect_to #pin, notice: "Pin was successfully updated!"
else
render 'edit'
end
end
def destroy
#pin.destroy
redirect_to root_path
end
def error
end
private
def pin_params
params.require(:pin).permit(:title, :description)
end
def find_pin
#pin = Pin.find(params[:id])
end
end
/views/pins/show.html.haml
%h1= #pin.title
%p= #pin.description
%p
%hr
%strong Submitted by
= #pin.user.email
Here, in the last line of show.html.haml, I want the #pin.user.email to be a link so that
the profile of the user (the one who submitted the article) can be accessed when clicked on it.
the profile of the user should list all of the articles submitted by him/her.
These are the two things that I'm trying to accomplish but don't know the code I should use for it. I don't have a users_controller. I did have one but I deleted it after it started messing with devise's routes. All answers are welcome, thanks in advance!
First Of All Create User Controller.
Redirect Show page line to user show action
Then you perform what you want.
For Ex.
link_to "User Profile", user_path(#pin.user.id)
users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find_by_id(params[:id])
#pins = #user.pins
end
end
/views/users/show.html.haml
User #user and #pins to Display What you want.
You forgot to define your show method
def show
#pin
end
having issues keep getting error undefined method `pins' for nil:NilClass, can someone explain how to fix this error. Been following a tutorial and recently got stuck.
pins_controller.rb
class PinsController < ApplicationController
before_action :find_pin, only: [:show, :edit, :update, :destroy]
def index
#pins = Pin.all.order("created_at DESC")
end
def new
#pin = current_user.pins.build
end
def create
#pin = current_user.pins.build(pin_params)
if #pin.save
redirect_to #pin, notice: "Successfully created new Pin"
else
render 'new'
end
end
def edit
end
def update
if #pin.update(pin_params)
redirect_to #pin, notice: "Pin was Successfully updated!"
else
render 'edit'
end
end
def destroy
#pin.destroy
redirect_to root_path
end
private
def pin_params
params.require(:pin).permit(:title, :description)
end
def find_pin
#pin = Pin.find(params[:id])
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 :pins
end
pin.rb
class Pin < ActiveRecord::Base
belongs_to :user
end
routes.rb
Rails.application.routes.draw do
devise_for :users
resources :pins
root "pins#index"
end
If you are using the gem Devise then the helper method current_user returns you the current logged in user in your session.
Pleases make sure a user is logged in/
You can make sure that the user is logged in by adding before_action :authenitcate_user! in your application controller(for all actions in your application).
If you are using devise, you might want to add
before_action :authenitcate_user!
method inside pins controller which ensures that the user is logged in.
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.
After installing devise and adding authentication & User model successfully, every time i try an sign up to my web app i can get to the sign in page and login but when i click submit i get NoMethodError in BookmarksController#index undefined method `page' for #
# GET /bookmarks
def index
error -> #bookmarks = current_user.bookmarks.order('created_at desc').page(params[:page])
end
# GET /bookmarks/1
bookmarks controller
class BookmarksController < ApplicationController
before_action :set_bookmark, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /bookmarks
def index
#bookmarks = current_user.bookmarks.order('created_at desc').page(params[:page])
end
# GET /bookmarks/1
def show
end
# GET /bookmarks/new
def new
#bookmark = current_user.bookmarks.new
end
# GET /bookmarks/1/edit
def edit
end
# POST /bookmarks
def create
#bookmark = current_user.bookmarks.new(bookmark_params)
if #bookmark.save
redirect_to #bookmark, notice: 'Bookmark was successfully created.'
else
render action: 'new'
end
end
# PATCH/PUT /bookmarks/1
def update
if #bookmark.update(bookmark_params)
redirect_to #bookmark, notice: 'Bookmark was successfully updated.'
else
render action: 'edit'
end
end
# DELETE /bookmarks/1
def destroy
#bookmark.destroy
redirect_to bookmarks_url, notice: 'Bookmark was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_bookmark
unless #bookmark = current_user.bookmarks.where(id: params[:id]).first
flash[:alert] = 'Bookmark not found.'
redirect_to root_url
end
end
# Only allow a trusted parameter "white list" through.
def bookmark_params
params.require(:bookmark).permit(:title, :url, :user_id)
end
end
bookmark.rb
class Bookmark < ActiveRecord::Base
belongs_to :user
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 :bookmarks
end
Remove call for page method from index action:
def index
#bookmarks = current_user.bookmarks.order('created_at desc')
end
Its not defined anywhere in the given code in the question. page method is usually used with will_paginate gem and you are not using it, so remove the call.