undefined method `any?' for nil:NilClass for <% if #users.any? %> - ruby

I am following the Micheal Hartl Ruby on Rails tutorial. In the 12 chapter, I am getting this error.
I am trying to display the following and the followers, but I am not able to.
Following are the codes:
show.html.erb
<% provide(:title, #title) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= gravatar_for #user %>
<h1><%= #user.name %></h1>
<span><%= link_to "view my profile", #user %></span>
<span><b>Microposts:</b> <%= #user.microposts.count %></span>
</section>
<section class="stats">
<%= render 'shared/stats' %>
<% if #users.any? %>
<div class="user_avatars">
<% #users.each do |user| %>
<%= link_to gravatar_for(user, size: 30), user %>
<% end %>
</div>
<% end %>
</section>
</aside>
<div class="col-md-8">
<h3><%= #title %></h3>
<% if #users.any? %>
<ul class="users follow">
<%= render #users %>
</ul>
<%= will_paginate %>
<% end %>
</div>
</div>
relationship_controller.rb
class RelationshipsController < ApplicationController
before_action :logged_in_user
def create
def create
#user = User.find(params[:followed_id])
current_user.follow(user)
respond_to do |format|
format.html { redirect_to #user }
format.js
end
def destroy
#user = Relationship.find(params[:id]).followed
current_user.unfollow(user)
respond_to do |format|
format.html { redirect_to #user }
format.js
end
end
end
user_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy,
:following, :followers]
before_action:correct_user, only: [:edit, :update]
before_action:admin_user, only: :destroy
def index
#users= User.paginate(page: params[:page])
end
def show
#user= User.find(params[:id])
#microposts = #user.microposts.paginate(page: params[:page], :per_page => 5)
end
def new
#user= User.new
end
def create
#user= User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def edit
#user= User.find(params[:id])
end
def update
#user= User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
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
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
def correct_user
#user= User.find(params[:id])
redirect_to(root_url) unless #user== current_user
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end

Your issue is that the show action is actually using the #user instead of #users instance variable.
Your section for stats will not work since it's expecting what it looks like a collection of User as it would from the index action.
Since you have the action for followers which sets the #user and #users instance variables you have to visit that action instead and the code on your show.html.erb template will most likely have to move to the show_follow.html.erb template.
UPDATE
You need to remove this section from your show.html.erb template
<section class="stats">
<%= render 'shared/stats' %>
<% if #users.any? %>
<div class="user_avatars">
<% #users.each do |user| %>
<%= link_to gravatar_for(user, size: 30), user %>
<% end %>
</div>
<% end %>
</section>
</aside>
<div class="col-md-8">
<h3><%= #title %></h3>
<% if #users.any? %>
<ul class="users follow">
<%= render #users %>
</ul>
<%= will_paginate %>
<% end %>
</div>

I saw your repository and seems like you have messed up the code, according to what you are following(Ruby on Rails - Micheal Hartl), this is what you need to change:
The code in your show.html.erb should be placed in show_follow.html.erb
After this follow the 12th chapter again and place the right code in show.html.erb.

Related

Beginner stuck on Ruby on Rails project "...must exist"

So my assignment asks me to generate a page that handles students, courses, and sections. I'm supposed to be using many_to_many or some similar method to be able to list all this shared data. My specific problem is that I created a new table (rails g scaffold enrollment students:references sections:references) that doesn't seem to work. when I attempt to create a new enrollment using a student and section, I get an error stating that "Section must exist" error . I have no idea where this error is coming from. The sections field in this view is only populated with existing sections, so the fact that it says "must exist" is very...confusing. Can anyone point me in the right direction to solve this? I've rebuilt this project 3 times trying different methods and am just... stuck. I'll post the relevant code, but if I'm wrong about which sections you may need to see, I'll happily post the rest.
class Enrollment < ApplicationRecord
belongs_to :section
belongs_to :student
end
<%= form_with(model: enrollment, local: true) do |form| %>
<% if enrollment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(enrollment.errors.count, "error") %>
prohibited this enrollment from being saved:</h2>
<ul>
<% enrollment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :student_id %>
<%= form.collection_select :student_id, Student.order(:student_name), :id,
:student_id, include_blank:true %>
</div>
<div class="field">
<%= form.label :course_id %>
<%= form.collection_select :course_id, Course.order(:name), :id, :name,
include_blank: true %>
</div>
<div class="field">
<%= form.label :sections_number %>
<%= form.collection_select :section_number, Section.all, :id,
:section_number, include_blank:false %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
class Section < ApplicationRecord
has_many :enrollments
has_and_belongs_to_many :students, through: :enrollments
belongs_to :course
def numsem
"#{course.name} #{course_id}"
end
end
L
-----------------------EDIT TO ADD CONTROLLER CODE----------------
class EnrollmentsController < ApplicationController
before_action :set_enrollment, only: [:show, :edit, :update, :destroy]
# GET /enrollments
# GET /enrollments.json
def index
#enrollments = Enrollments.all
end
# GET /enrollments/1
# GET /enrollments/1.json
def show
end
# GET /enrollments/new
def new
#enrollment = Enrollments.new
#sections = Section.all
#students = Student.all
end
# GET /enrollments/1/edit
def edit
end
# POST /enrollments
# POST /enrollments.json
def create
#enrollment = Enrollments.new(enrollment_params)
respond_to do |format|
if #enrollment.save
format.html { redirect_to #enrollment, notice: 'Enrollments was
successfully created.' }
format.json { render :show, status: :created, location: #enrollment }
else
format.html { render :new }
format.json { render json: #enrollment.errors, status:
:unprocessable_entity }
end
end
end
# PATCH/PUT /enrollments/1
# PATCH/PUT /enrollments/1.json
def update
respond_to do |format|
if #enrollment.update(enrollment_params)
format.html { redirect_to #enrollment, notice: 'Enrollments was
successfully updated.' }
format.json { render :show, status: :ok, location: #enrollment }
else
format.html { render :edit }
format.json { render json: #enrollment.errors, status:
:unprocessable_entity }
end
end
end
# DELETE /enrollments/1
# DELETE /enrollments/1.json
def destroy
#enrollment.destroy
respond_to do |format|
format.html { redirect_to enrollments_index_url, notice: 'Enrollments was
successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_enrollment
#enrollment = Enrollments.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list
through.
def enrollment_params
params.require(:enrollment).permit(:student_id, :section_id)
end
end
Section must exist
The error is because you are trying to save the #enrollment with a nil section_id which raises that exception. The problem lies with your form where you have this
<%= form.collection_select :section_number, Section.all, :id,
:section_number, include_blank:false %>
which should be
<%= form.collection_select :section_id, Section.all, :id,
:section_number, include_blank:false %>

rails application displaying blank space in users(venue) place

I am able to post an event but when I select the user to post as, the dropdown menu shows empty spaces where the user (venue name) should be. I have tried everything that I can think of. Any ideas would be greatly appreciated.
I am on rails 4. I am using devise as well.
here are my files:
show.html.erb:
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #gig.user.venue_name %>
</p>
<p>
<strong>Event:</strong>
<%= #gig.event %>
</p>
<p>
<strong>Date:</strong>
<%= #gig.date %>
</p>
<p>
<strong>Doors:</strong>
<%= #gig.doors %>
</p>
<p>
<strong>Showtime:</strong>
<%= #gig.showtime %>
</p>
<p>
<strong>Age:</strong>
<%= #gig.age %>
</p>
<p>
<strong>Price:</strong>
<%= #gig.price %>
</p>
<p>
<strong>Description:</strong>
<%= #gig.description %>
</p>
<%= link_to 'Edit', edit_gig_path(#gig) %> |
<%= link_to 'Back', gigs_path %>
index.html.erb:
<p id="notice"><%= notice %></p>
<div class="page-header">
<h1>All Gigs</h1>
</div>
<% #gigs.each do |gig| %>
<div class="gig">
<strong><%= gig.user.venue_name %></strong>
<p><%= gig.event %></p>
<p><%= gig.date %></p>
<p><%= gig.doors %></p>
<p><%= gig.showtime %></p>
<p><%= gig.age %></p>
<p><%= gig.price %></p>
<p><%= gig.description %></p>
<div class="meta">
<%= link_to time_ago_in_words(gig.created_at) + " ago", gig %>
<span class="admin">
| <%= link_to 'Edit', edit_gig_path(gig) %> |
<%= link_to 'Delete', gig, method: :delete, data: { confirm: 'Are you sure?' } %>
</span>
</div>
</div>
<% end %>
</tbody>
</table>
gig.rb:
class Gig < 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 :gigs
end
_form.html.erb:
<%= simple_form_for(#gig, html: {class: "form-horizontal"}) do |f| %>
<% if #gig.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#gig.errors.count, "error") %> prohibited this gig from being saved:</h2>
<ul>
<% #gig.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.input :user_id, collection: User.all, label_method: :venue_name %>
<%= f.input :event %>
<%= f.input :date %>
<%= f.input :doors %>
<%= f.input :showtime %>
<%= f.input :age %>
<%= f.input :price %>
<%= f.input :description %>
<div class="form-actions">
<%= f.button :submit %>
</div>
db migrate add user id to gig
class AddUserIdToGigs < ActiveRecord::Migration
def change
add_column :gigs, :user_id, :integer
add_index :gigs, :user_id
remove_column :gigs, :name
end
end
gigs_controller.rb
class GigsController < ApplicationController
before_action :set_gig, only: [:show, :edit, :update, :destroy]
# GET /gigs
# GET /gigs.json
def index
#gigs = Gig.all
end
# GET /gigs/1
# GET /gigs/1.json
def show
end
# GET /gigs/new
def new
#gig = Gig.new
end
# GET /gigs/1/edit
def edit
end
# POST /gigs
# POST /gigs.json
def create
#gig = Gig.new(gig_params)
respond_to do |format|
if #gig.save
format.html { redirect_to #gig, notice: 'Gig was successfully created.' }
format.json { render :show, status: :created, location: #gig }
else
format.html { render :new }
format.json { render json: #gig.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /gigs/1
# PATCH/PUT /gigs/1.json
def update
respond_to do |format|
if #gig.update(gig_params)
format.html { redirect_to #gig, notice: 'Gig was successfully updated.' }
format.json { render :show, status: :ok, location: #gig }
else
format.html { render :edit }
format.json { render json: #gig.errors, status: :unprocessable_entity }
end
end
end
# DELETE /gigs/1
# DELETE /gigs/1.json
def destroy
#gig.destroy
respond_to do |format|
format.html { redirect_to gigs_url, notice: 'Gig was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_gig
#gig = Gig.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def gig_params
params.require(:gig).permit(:name, :event, :date, :doors, :showtime, :age, :price, :description, :user_id)
end
end
Solved it:
After running irb, I noticed that venues was null in the db. Therefore, I realized that I had to as venues in devise by creating new forms.

Ruby on Rails First argument in form cannot contain nil or be empty

I used the standard Ruby on Rails generate scaffolding. I need help to find out how to move a form from the "New" view to the "Posts" view (Main Page). I keep on getting the error "First argument in form cannot contain nil or be empty". Here is my "Posts" view code. It works fine in the "New" view but not the "Posts" view.
Posts View:
<%= form_for(#post) do |f| %>
New View:
<h1>New post</h1>
<%= render 'form' %>
<%= link_to 'Back', posts_path %>
Form View:
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
</div>
<div class="field">
<%= f.label :casino %>
<%= f.text_field :casino %>
</div>
</div>
<div class="field">
<%= f.label :City %>
<%= f.text_field :City %>
</div>
</div>
</div>
<div class="field">
<%= f.label :State %>
<%= f.text_field :State %>
</div>
</div>
<div class="field">
<%= f.label :Country %>
<%= f.text_field :Country %>
</div>
<div class="field">
<%= f.label :Game %>
<%= f.text_field :title %>
<div class="field">
<%= f.label :Minimum %>
<%= f.text_field :text %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
CONTROLLER CODE:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :text, :casino, :City, :State, :Country)
end
end
Add this line in index action of PostsController
#post = Post.new
This should solve your problem :)
SOLUTION:
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
#post = Post.new
end

Why did I get a "No Method" error?

I am currently going through "Agile web development with Rails - 4th edition" and I am stuck.
The checkout button is supposed to bring up an orders page, but instead I get this error:
NoMethodError in Orders#new
Showing C:/Sites/depot/app/views/orders/_form.html.erb where line #1 raised:
undefined method `model_name' for NilClass:Class
Extracted source (around line #1):
1: <%= form_for(#order) do |f| %>
2: <% if #order.errors.any? %>
3: <div id="error_explanation">
4: <h2><%= pluralize(#order.errors.count, "error") %>
After spending a lot of time trying to figure this out, I copied all the source code from the books website, which still didn't work. I even checked the errata and book forums and found nothing.
What am I doing wrong?
This is the code from the views/orders/_form.html.erb:
<%= form_for(#order) do |f| %>
<% if #order.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#order.errors.count, "error") %>
prohibited this order from being saved:</h2>
<ul>
<% #order.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<!-- START_HIGHLIGHT -->
<%= f.text_field :name, size: 40 %>
<!-- END_HIGHLIGHT -->
</div>
<div class="field">
<%= f.label :address %><br />
<!-- START_HIGHLIGHT -->
<%= f.text_area :address, rows: 3, cols: 40 %>
<!-- END_HIGHLIGHT -->
</div>
<div class="field">
<%= f.label :email %><br />
<!-- START_HIGHLIGHT -->
<%= f.email_field :email, size: 40 %>
<!-- END_HIGHLIGHT -->
</div>
<div class="field">
<%= f.label :pay_type %><br />
<!-- START_HIGHLIGHT -->
<%= f.select :pay_type, Order::PAYMENT_TYPES,
prompt: 'Select a payment method' %>
<!-- END_HIGHLIGHT -->
</div>
<div class="actions">
<!-- START_HIGHLIGHT -->
<%= f.submit 'Place Order' %>
<!-- END_HIGHLIGHT -->
</div>
<% end %>
This is the Orders Controller:
class OrdersController < ApplicationController
def index
#orders = Order.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #orders }
end
end
# GET /orders/1
# GET /orders/1.json
def show
#order = Order.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #order }
end
end
# GET /orders/new
# GET /orders/new.json
def new
#cart = current_cart
if #cart.line_items.empty?
redirect_to store_url, notice: "Your cart is empty"
return
end
#order = Order.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #order }
end
end
# GET /orders/1/edit
def edit
#order = Order.find(params[:id])
end
# POST /orders
# POST /orders.json
def create
#order = Order.new(params[:order])
#order.add_line_items_from_cart(current_cart)
respond_to do |format|
if #order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
format.html { redirect_to store_url, notice:
'Thank you for your order.' }
format.json { render json: #order, status: :created,
location: #order }
else
#cart = current_cart
format.html { render action: "new" }
format.json { render json: #order.errors,
status: :unprocessable_entity }
end
end
end
# PUT /orders/1
# PUT /orders/1.json
def update
#order = Order.find(params[:id])
respond_to do |format|
if #order.update_attributes(params[:order])
format.html { redirect_to #order, notice: 'Order was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
#order = Order.find(params[:id])
#order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :ok }
end
end
end
This is the Order model:
class Order < ActiveRecord::Base
PAYMENT_TYPES = [ "Check", "Credit card", "Purchase order" ]
has_many :line_items, dependent: :destroy
# ...
validates :name, :address, :email, presence: true
validates :pay_type, inclusion: PAYMENT_TYPES
end
The form view believes that #order is nil here:
1: <%= form_for(#order) do |f| %>
What is the path that you are hitting in the browser? /orders/new
It does appear that Order#new is setting #order to Order.new, so I am wondering if you are actually hitting that controller.
Rails will route requests to controller actions based on what is setup in routes.rb. Run rake routes to see the routes you can access in the url.
Rails has conventions such that if you access the /orders/new using a simple GET request, it will route your request to the new action of the OrdersController and will attempt to render the associated app/views/orders/new.html.erb - unless you customize some aspect of this.
I would add a puts "Order is set to: #{#order}" in the new action following the #order = Order.new assignment to ensure it's actually going through that path.

undefined method `memo' for nil:NilClass error using best_in_place

I've created a simple memo feature for my app, and have successfully implemented in-place editing using the best_in_place gem.
The problem I am having is creating new memos using in-place editing, the following code returns undefined methodmemo' for nil:NilClass`
#partial for logged in users on homepage
<% provide(:title, current_user.name) %>
<h1>Hey
<%= current_user.name %>
</h1>
<div class="row-fluid">
<div class="span12">
<div class="row-fluid">
<div class="span6">
<h2>Memos</h2>
<ul id="memos" data-update-url="<%= sort_memos_url %>">
<%# render #memos %>
<% #memos.each do |memo| %>
<%= content_tag_for :li, memo do %>
<%= best_in_place memo, :memo %>
<% end %>
<% end %>
</ul>
<p><%# link_to "Add a memo", new_memo_path %></p>
<p><%= best_in_place #memo, :memo, :path => new_memo_path, :nil => "Add a memo" %></p>
</div>
<div class="span6"><h2>Coming up...</h2></div>
</div>
</div>
</div>
#memos controller
def index
#memos = Memo.order("position")
end
def show
#memo = Memo.find(params[:id])
end
def new
#memo = Memo.new
end
def create
#memo = Memo.new(params[:memo])
if #memo.save
redirect_to #memo, notice: "Successfully created memo."
else
render :new
end
end
def edit
#memo = Memo.find(params[:id])
end
def update
#memo = Memo.find(params[:id])
#memo.update_attributes(params[:memo])
respond_with #memo
end
def sort
params[:memo].each_with_index do |id, index|
Memo.update_all({position: index+1}, {id: id})
end
render nothing: true
end
#home page controller
respond_to :html, :json
def home
if signed_in?
#memos = Memo.order("position")
end
end
def sort
params[:memo].each_with_index do |id, index|
Memo.update_all({position: index+1}, {id: id})
end
render nothing: true
end
def help
end
end
I am new to rails and programming in general so I am sure it is a simple fix, none-the-less it's one that I cannot seem to remedy.
Have a look at (see 3.3.4):
http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials
Using partials and variables, means you need to stick to a certain naming convention. If your not doing that, then you need to send the variable (from the calling view) with it.
<%= render :partial => "form", :locals => { :zone => #zone } %>

Resources