NameError in Users#show - Rails - ruby-on-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 %>

Related

Clicking on a Username of another user links to my profile instead of the user's profile

I need help with this my code,that displays list of posts of users along with their username.What i want is, when i click on a username of a particular post, it should send me to that user's profile. instead, it send's to my own profile or the current user's profile whiles i want it to link me to the username i have clicked profile. (e.g like when you click on a username on Instagram, it links you to the user's profile so you can follow or unfollow and see their post)
Please i need help. what i'm i not doing right in my code.
i'm on rails 5.2.3 & ruby 2.3.3
Home
<div class="posts">
<% #posts.each do |post| %>
<section class="post">
<div class="user">
<div class="avatar">
<img src="assets/avater.jpg">
</div>
<%= link_to post.user.username, user_path(post.user), class: 'username' %>
</div>
<%= image_tag post.image, class: 'main-image' %>
<div class="description">
<% post.description.to_s.split(' ').each do |word| %>
<% if word.start_with?('#') %>
<%= link_to word, search_index_path(query: word) %>
<% else %>
<%= word %>
<% end %>
<% end %>
</div>
</section>
<% end %>
<%= paginate #posts %>
</div>
routes
Rails.application.routes.draw do
get 'search/index'
devise_for :users
get 'home/index'
resources :posts
root 'home#index'
resources :users, only: [:show, :edit, :update]
resources :posts, only: [:new, :create, :show, :destroy]
end
users controller
class UsersController < ApplicationController
before_action :find_user
def show
#user = User.find(params[:id])
#posts = current_user.posts.order(created_at: :desc)
end
def edit
end
def update
current_user.update(user_params)
redirect_to current_user
end
private
def find_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:username, :name, :website,:bio, :email, :phone, :gender, :avatar)
end
end
post controller
class PostsController < ApplicationController
def new
#post = current_user.posts.build
end
def create
#post = Post.create(post_params)
redirect_to root_path
end
def show
#post = Post.find(params[:id])
end
def destroy
#post = current_user.posts.find(params[:id])
#post.destroy
redirect_to user_path(current_user)
end
private
def post_params
params.require(:post).permit(:description, :image, :user_id)
end
end
home controller
class HomeController < ApplicationController
before_action :authenticate_user!
def index
#posts = Post.order(created_at: :desc).page(params[:page]).per(5)
end
end
I guess the problem is that on the show method from users_controller, you are getting the posts from current_user instead of the user, it should be #posts = #user.posts.order(created_at: :desc)

What is causing NoMethodError in my CRUD?

I am student working on my first project on my own. The user is supposed to be able to create a to-do list. I have my form partial displayed and am trying to now render the list items through a partial. After altering my routes.rb and items_controller.rb I still receive NoMethodError.
Here is the stack trace.
Completed 500 Internal Server Error in 23ms (ActiveRecord: 0.2ms)
ActionView::Template::Error (undefined local variable or method `items' for #<#<Class:0x007fa1c3b4e238>:0x007fa1bd6f2258>):
1: <% items.each do |i| %>
2: <%= i.name %>
3: <% end %>
app/views/items/_item.html.erb:1:in `_app_views_items__item_html_erb___4201771908086516106_70166314068980'
app/views/users/show.html.erb:5:in `_app_views_users_show_html_erb__1693372631105662933_70166313045680'
items_controller.rb
class ItemsController < ApplicationController
def index
#items = Item.all
end
def show
#item = Item.find(params[:id])
end
def new
#item = Item.new
end
def edit
#item = Item.find(params[:id])
end
def create
#item = Item.new(params.require(:item).permit(:name))
if #item.save
flash[:notice] = "The item was added to your list."
redirect_to :show
else
flash[:error] = "There was a problem creating your item."
redirect_to :new
end
end
end
routes.rb
Rails.application.routes.draw do
get 'welcome/index'
get 'welcome/about'
# resources :welcome, only: [] do
# collection do
# get 'about'
# get 'index'
# end
# end
devise_for :users
resources :users, only: [:show]
resources :items
root to: 'welcome#index'
end
users/show.html.erb
<h1>Welcome <%= current_user.name %></h1>
<p>Add an item</p>
<%= render partial: 'items/form', locals: { item: #new_item } %>
<%= render partial: 'items/item', locals: { item: #items } %>
items/_item.html.erb
<% items.each do |i| %>
<%= i.name %>
<% end %>
EDIT: Here is my users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!
def show
#user = User.find(params[:id])
#new_item = Item.new
end
end
You need to use local variable item, which you passed to the partial _item.html.erb. :
<% item.each do |i| %>
<%= i.name %>
<% end %>
and ...
class UsersController < ApplicationController
before_action :authenticate_user!
def show
#user = User.find(params[:id])
#new_item = Item.new
#items = Item.all
end
end

First argument in form cannot contain nil or be empty with Gamepost

Recieve this error in my Game page in Rails 4
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
_Gamepost_form.html.erb
<%= form_for (#gamepost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new game sale..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
Controller
class GamepostsController < ApplicationController
before_action :signed_in_user, only: [:create, :destroy, :]
before_action :correct_user, only: :destroy
def index
#gamepost = current_user.gameposts.build
end
def create
#gamepost = current_user.gameposts.build(gamepost_params)
if #gamepost.save
flash[:success] = "Game Sale created!"
redirect_to root_url
else
#gamefeed_items = []
render 'static_pages/home'
end
end
def destroy
#gamepost.destroy
redirect_to root_url
end
private
def gamepost_params
params.require(:gamepost).permit(:content)
end
def correct_user
#gamepost = current_user.gameposts.find_by(id: params[:id])
rescue
redirect_to root_url
end
end
Have a similar example using microposts and its working fine no idea why this instance is not working
After the answer Vee provided,
ActionView::Template::Error (undefined method `any?' for nil:NilClass):
1: <% if #gamefeed_items.any? %>
2: <ol class="gameposts">
3: <%= render partial: 'shared/gamefeed_item', collection: #gamefeed_items %>
This shows up in same page
Following up in the comments in your question.
Looks like you are rendering that form from your index action.
class GamepostsController < ApplicationController
before_action :signed_in_user, only: [ :index, :create, :destroy]
...
def index
#gamepost = current_user.gameposts.build
end
...
end
Note that, you also need to add :index and not :new in before_action :signed_in_user. This is to ensure that the current_user becomes available in so that current_user.gameposts.build does not fail!

Why isn't this portion of HTML rendering and why do I get a undefined method `cardsets' for nil:NilClass in Rails?

I'm trying to add a flashcards(cardsets) feature in Rails and I'm having some problems implementing this as I'm getting an undefined methodcardsets' for nil:NilClass` error
I can get the page to render if I change: <% if #user.cardsets.any? %> to <% unless #cardsets.any? %> but the corresponding cardsets are being shown when I do this.
Here is the html.erb code that is producing this error:
<% provide(:title, "Flashcards") %>
<h1>Flashcards</h1>
<div class="row">
<aside class="span3">
<%= render "shared/cardset_form" %>
</aside>
<div class="span6">
**<% if #user.cardsets.any? %>**
<h3>Flashcard Sets (<%= #user.cardsets.count %>)</h3>
<ol class="cardsets">
<% #user.cardsets.each do |cardset| %>
<li>
<span class="topic"><%= link_to cardset.topic, show_cardset_path(cardset) %></span>
<%= link_to "edit", edit_cardset_path(cardset) %>
<%= render partial: "shared/delete_link", locals: {item: cardset} %>
</li>
<% end %>
</ol>
<% end %>
</div>
</div>
I've starred the line that is producing the undefined methodcardsets' for nil:NilClass` error.
This is what's in my cardsets_controller.rb:
class CardsetsController < ApplicationController
before_action :signed_in_user, only: [:new, :index, :create, :edit, :destroy, :update]
before_action :correct_user, only: [:edit, :update, :destroy]
def index
#cardsets = Cardset.all
end
def show
#cardset = Cardset.find(params[:id])
end
def create
#cardset = current_user.cardsets.build(cardset_params)
if #cardset.save
flash[:success] = "A new set of flashcards have been created!"
redirect_to #cardset
else
render "new"
end
end
def new
#cardset = Cardset.new
end
def edit
end
def update
#cardset = Cardset.find(params[:id])
if #cardset.update_attributes(cardset_params)
flash[:success] = "You've updated your flashcards!"
redirect_to #cardset
else
render "edit"
end
end
def destroy
#cardset = Cardset.find(params[:id])
#cardset.delete
redirect_to cardsets_path
end
private
def cardset_params
params.require(:cardset).permit(:topic, :description)
end
def correct_user
#cardset = current_user.cardsets.find_by_id(params[:id])
redirect_to root_url if #cardset.nil?
end
end
Here is the code in my cardset.rb file:
class Cardset < ActiveRecord::Base
belongs_to :user
validates :user_id, presence: true
validates :topic, presence: true
end
Here is the code in my user.rb file:
class User < ActiveRecord::Base
has_many :cardsets
(...a bunch of other code...)
end
If anyone could provide some help or suggestions on where I may be going wrong I'd greatly appreciate it!
Thanks!
As far as I can tell, you aren't setting #user in your Controller, so #user is nil.
You probably want to either define #user or maybe you meant to use #cardsets.

Rails: NoMethodError in Users#show

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 %>

Resources