Rails Beginner NoMethodError in PinsController#new - ruby-on-rails

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.

Related

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.

Can't establish connection between controllers

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

Rails - Want to build a profile for user after using Devise gem as sign up

I am using Devise for registration. But I want to build a profile for user so that where user can fill their info.
I want a single for profile for user but whenever new_profile_path another profile is created for that user, I want to avoid user to go to new_profile_path or create new profile after 1 profile is created.
here is the code
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_one :profile
has_many :statuses
end
profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
validates_associated :user
end
profiles_controller.erb
class ProfilesController < ApplicationController
before_action :authenticate_user!
before_action :find_profile, only: [:show, :edit, :update, :destroy]
respond_to :html
def index
#profiles = Profile.all
end
def new
#profile = Profile.new
end
def create
#profile = Profile.new(profile_params)
#profile.user_id = current_user.id
#profile.save
respond_with(#profile)
end
def show
#profile = Profile.find(params[:id])
end
def edit
end
def update
#profile.update(profile_params)
respond_with(#profile)
end
private
def find_profile
#profile = Profile.find(params[:id])
end
def profile_params
params.require(:profile).permit(:first_name, :last_name, :birth_date,
:gender, :bio, :personal_website, :linkedin_profile, :facebook_profile,
:mobile_no, :telephone_no)
end
end
This is the current code for creating Profile for user. But every time a profile is created for user through new_profile_path. How can I avoid it?
Thanks in advance for giving your time.
One solution is:
# in User model
has_one :profile
before_create :build_profile, unless: :profile
Alternatively:
# in User model
has_one :profile
after_create :create_profile, unless: :profile
The conditional unless: :profile is there so that it doesn't overwrite a profile that was already added before the user was created.
When your using associations, you have to use build instead of new.... In your Profile controller...
def new
#profile = current_user.build_profile
end
def create
#profile = current_user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile saved"
redirect_to current_user_path
else
flash[:error] = "Error"
render: new
end
end
This will make sure that only one profile is created for each user...
def edit
#profile = current_user.profile.find(params[:id])
end
def update
#profile = current_user.profile.find(params[:id])
if #profile.update_attributes(profile_params)
flash[:success] = "Successfully updated" # Optional
redirect_to user_path
else
flash[:error] = "Error" # Optional
render :edit
end
end

Rails no method error since installing devise?

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.

NoMethodError in BookmarksController#index

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.

Resources