Rails: NoMethodError in Users#show - ruby-on-rails

I'm new to Rails and I've been wandering aimlessly around stackoverflow trying to find a solution to my problem but can't seem to figure it out. I'm doing chapter 10 of Michael Hartl's tutorial and when I try to view the profile of a specific user the localhost:3000 page I get the following error messages:
"NoMethodError in Users#show"
followed by
"undefined method `name' for nil:NilClass".
The source is listed as the first line of my show.html.erb file but I can't see anything wrong with the code.
The home page works fine and the users index is viewable but beyond that it doesn't work. I understand that this could mean that the #user object is nil but I'm not sure how to fix this. My Rspec tests are also failing hard - any help would be greatly appreciated.
My users_controller.rb file:
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :edit, :update, :destroy]
# Arranges for a particular method to be called before the given actions.
before_filter :correct_user, only: [:edit, :update]
before_filter :admin_user, only: :destroy # Restricts the destroy action to admins.
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def index
#users = User.paginate(page: params[:page])
end
def edit
# #user = User.find(params[:id])
end
def update
# #user = User.find(params[:id])
if #user.update_attributes(params[:user])
flash[:success] = "Profile updated"
sign_in #user
redirect_to #user
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to users_url
end
private
# def signed_in_user
# unless signed_in?
# store_location
# redirect_to signin_url, notice: "Please sign in."
# end
# end
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page])
end
end
My show.html.erb file:
<% provide(:title, #user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</section>
</aside>
<div class="span8">
<% if #user.microposts.any? %>
<h3>Microposts (<%= #user.microposts.count %>)</h3>
<ol class="microposts">
<%= render #microposts %>
</ol>
<%= will_paginate #microposts %>
<% end %>
</div>
</div>
And users_helper.rb
module UsersHelper
# Returns the Gravatar (http://gravatar.com/) for the given user.
def gravatar_for(user, options = { size: 50 })
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
size = options[:size]
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
image_tag(gravatar_url, alt: user.name, class: "gravatar")
end
end

Here #user is nil. Because there is no record with the id (params[:id]). Thats why this error is coming.
<h1>
<%= gravatar_for #user %>
<%= !#user.nil? #user.name : "" %>
</h1>
It will check whether the #user having any record, if its having it will display it's name else it will display empty.

Your query doesn't find a user:
#user = User.find(params[:id])
does apparently return nil.
Please check that a user with the given ID exists. Additionally, you should make your actions fail safely when no object(s) are found:
<% if #user.nil? %>
<% provide(:title, 'Not found') %>
No user with that ID has been found.
<% else %>
<!-- Contents of your current show.html.erb -->
<% end %>

Related

NameError in Users#show - Rails

I am following Michael Hurtl's Rails Tutorial and In Chapter 11 When i want to view the profile page of the User i get this error :
NameError in Users#show undefined local variable or method `micropost' and This line of Code is highlighted in red :
<%= link_to micropost.user.name , micropost.user%>
Here's My code:
microposts_controller.rb
class MicropostsController < ApplicationController
before_action :authenticate_user! , only: [:create,:destroy]
def create
#micropost = current_user.microposts.build(micropost_params)
if #micropost.save
flash[:success] = "Micropost created"
redirect_to root_url
else
render 'pages/home'
end
end
def destroy
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
end
users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user! , only: [:edit,:update,:destroy]
def index
#users = User.all
end
def show
#user = User.find(params[:id])
#microposts = #user.microposts
end
end
microposts/_microposts.html.erb
<%= link_to micropost.user.name , micropost.user%>
views/users/show.html.erb
<h2>User Profile</h2>
<% if #user.microposts.any? %>
<h3>Microposts</h3>
<%= #user.microposts.count%>
<%= render 'microposts/microposts' %>
<%end%>
it seems you didn't set micropost variable to partial
you can fix it in next way:
<%= render partial: 'microposts/_microposts', collection: #microposts %>
You should have something like this in your partial:
<% #microposts.each do |micropost| %>
<%= link_to micropost.user.name , micropost.user%>
<% end %>

Ruby on Rails - show_user_path NoMethodError in Users#show

I am a begginer in Rails, im following code from a book and i am trying stuff to see if it breaks/works, anyway heres my UserControllers classUserController
class UsersController < ApplicationController
def new
#user = User.new
end
def edit
#user = User.find(params[:id])
end
def show
#user = User.find(params[:id])
end
def create
#user = User.new(params[:user])
if #user.save
redirect_to #user, :notice => 'Cadastro realizado'
else
render :new
end
end
end
And heres my show.html.erb
<p id="notice"><%=notice%></p>
<h2>Perfil: <%=#user.full_name %></h2>
<ul>
<li>Localização: <%= #user.location %> </li>
<li>Bio: <%= #user.bio %></li>
</ul>
<%= link_to 'Editar Perfil', edit_user_path(#user) %>
<%= link_to 'Mostrar Perfil', show_user_path(#user) %>
My problem is in the last line, when i try to acess this page i get a NomethodError,i am trying to understand why, why can i just change that to #user and the page works?
Try:
<%= link_to 'Mostrar Perfil', user_path(#user) %>
or even just
<%= link_to 'Mostrar Perfil', #user %>
In order to see how to name the routes, open a console and run
rake routes

Ruby on Rails Tutorial Michael Hart - Users not displaying on users index view (Chapter 9)

Chapter: 9.2 pages 405
Problem: None of the users names or avatars are being displayed.
users/index
<% provide(:title, 'All users') %>
<h1>All users</h1>
<ul class="users">
<% #users.each do |user| %>
<li>
<% gravatar_for user, size: 52 %>
<% link_to user.name, user %>
</li>
<% end %>
</ul>
UsersController
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :edit, :update]
before_filter :correct_user, only: [:edit, :update]
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
# Handle a successful save
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def index
#users = User.all
end
def edit
#user = User.find(params[:id])
end
def update
if #user.user_attributes(params[:users])
flash[:success] = "Profile updated"
sign_in #user
redirect_to #user
else
render 'edit'
end
end
private
def signed_in_user
redirect_to signin_path, notice: "Please sign in." unless signed_in?
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user)
end
end
sample_data.rake
namespace :db do
desc "Fill database with sample data"
task populate: :environment do
User.create!(name: "Example User",
email: "example#railstutorial.org",
password: "foobar",
password_confirmation: "foobar")
99.times do |n|
name = Faker::Name.name
email = "example-#{n+1}#railstutorial.org"
password = "password"
User.create!(name: name,
email: email,
password: password,
password_confirmation: password)
end
end
end
Please let me know if I am missing any code you need to see, and if there is any misunderstanding in my question. Thank you for your help and time.
You're not actually printing out the content in your views.
<% will evaluate the content but not print it; <%= will evaluate it and print it.
So you need to modify these two lines:
<% gravatar_for user, size: 52 %>
<% link_to user.name, user %>
to add the missing =.
Use %= to display in HTML:
<li>
<%= gravatar_for user, size: 52 %>
<%= link_to user.name, user %>
</li>

NoMethodError in Static_pages#home for method id

Newbie again in Rails. Following Michael Hartl's tutorial on rails and I'm trying to pass the last section and I get this error
undefined method `id' for #<String:0x3794b80>
It comes from my _feed_item.html.erb and I don't understand why I'm getting this error.
<li id="<%= feed_item.id %>">
<%= link_to gravatar_for(feed_item.user), feed_item.user %>
<span class="user">
<%= link_to feed_item.user.name, feed_item.user %>
</span>
<span class="content"><%= feed_item.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
</span>
<% if current_user?(feed_item.user) %>
<%= link_to "delete", feed_item, method: :delete, data: { confirm: "You sure?" }, title: feed_item.content %>
<% end %>
</li>
Hey guys, sorry I feel; asleep after.
When reviewing all my controllers I don't particularly see where it was defined however it did work before I started the last task so I don't know what happened in between.
Here is the user_controller
class UsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :edit, :update]
before_filter :correct_user, only: [:edit, :update]
before_filter :admin_user, only: :destroy
def new
#user=User.new
end
def create
#user=User.new(params[:user])
if #user.save
#Handle a save
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
def show
#user=User.find(params[:id])
#microposts=#user.microposts.paginate(page: params[:page])
end
def edit
#user=User.find(params[:id])
end
def update
#user=User.find(params[:id])
if #user.update_attributes(params[:user])
flash[:success]="Successfully updated your profile"
sign_in #user
redirect_to #user
else
render 'edit'
end
end
def correct_user
#user=User.find(params[:id])
redirect_to(root_path) unless current_user?(#user)
end
def index
#users=User.paginate(page: params[:page])
end
def destroy
User.find(params[:id]).destroy
flash[:success]="User destroyed"
redirect_to users_url
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
def following
#title="Following"
#user=User.find(params[:id])
#users=#user.followed_users.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
end
micrpost_controller
class MicrpostsController< ApplicationController
before_filter :signed_in_user, only: [:create, :destroy]
def index
end
def create
#micropost=current_user.microposts.build(params[:micropost])
if #micropost.save
flash[:success]="Micropost Created!"
redirect_to root_url
else
#feed_items = []
render 'static_pages/home'
end
end
def destroy
#micropost.destroy
redirect_to root_url
end
def correct_user
#micropost=current_user.microposts.find_by_id(params[:id])
redirect_to root_url if #micropost.nil?
end
end
I got it to work people. The issues was in my micropost model.
def self.from_users_followed_by(user)
followed_user_ids= "SELECT followed_id FROM relationships WHERE follower_id=:user_id",
where("user_id IN (#{followed_user_ids}) OR user_id=:user_id", user_id: user)
end
should have been
def self.from_users_followed_by(user)
followed_user_ids= "SELECT followed_id FROM relationships WHERE follower_id=:user_id"
where("user_id IN (#{followed_user_ids}) OR user_id=:user_id", user_id: user.id)
end

Create check box form from rendered members to send email - Ruby on Rails

I've got a team members page which pulls through the users associated with a university sports club, I'm trying to get it to produce a check box next to each member so that a member of the committee can simply select several members and on pressing a submit button the system will send an email to them.
I tried <%= check_box_tag(<%= render #users %>) %> but didn't have any luck
show_selection.html.rb - This is the page that renders the users
<% if signed_in? %>
<% if current_user.captain? %>
Welcome, select members to send a message to below
<table summary="Team members">
<tr>
<td class="main">
<% unless #users.empty? %>
<ul class="users">
<%= render #users %>
</ul>
<%= will_paginate #users %>
<% end %>
</td>
</tr>
</table>
<br>
<br>
<% else %>
<h1>An error has occured</h1>
<br>
<p>It looks like you're trying to access a restricted page <%= link_to "Please Click Here", '/' %> </p>
<% end %>
<% else %>
An error has occured
<br>
<p>It looks like you're trying to access a restricted page <%= link_to "Please Click Here", '/' %> </p>
<% end %>
users_contorller.rb
class UsersController < ApplicationController
before_filter :authenticate, :only => [:index, :edit, :update, :destroy]
before_filter :correct_user, :only => [:edit, :update]
before_filter :admin_user, :only => :destroy
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(:page => params[:page])
#title = #user.name
#admins = User.where(:admin => "t")
#captains = User.where(:captain => "t")
#clubs = User.where(:captain => "t")
end
def new
#user = User.new
#title = "Sign up"
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to University Sports!"
redirect_to #user
UserMailer.welcome_email(#user).deliver
else
#title = "Sign up"
render 'new'
end
end
def edit
#title = "Edit user"
end
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
flash[:success] = "Profile updated."
redirect_to #user
else
#title = "Edit user"
render 'edit'
end
end
def index
#users = User.paginate(:page => params[:page])
end
#def admins
# #users = User.admins
# render "users/index"
#end
def admins
#admins=User.where(:admin => "t")
end
def captains
#captains=User.where(:captain => "t")
end
def clubs
#clubs=User.where(:captain => "t")
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to users_path
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
def selection
#title = "Selection"
#user = User.find(params[:id])
#users = #user.followers.paginate(:page => params[:page])
render 'show_selection'
end
private
def authenticate
deny_access unless signed_in?
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_path) unless current_user?(#user)
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
end
Firstly you will need to wrap this in a form to handle the submission of the selected members to email. The form should be posted to a mailer controller or an action to handle the selected members for emailing.
<%= render #users %>
This will render a partial for each of the objects inside #users. You should add the checkbox inside this partial in order to render it for each member.
You will have something like this in your partial
<%= check_box_tag "user_ids[]", user.id %>
Ryan has a railscast that will point you out the in right direction of how to implement. This is about updating the records, but you can modify the code to work with your scenario.
http://railscasts.com/episodes/52-update-through-checkboxes

Resources