Ryan Ballow
Ryan Ballow

Reputation: 45

Undefined Method Error in Rails View (no other answer's solutions address this)

and thanks in advance.

I have a very basic rails application, that accepts user input from a form, and displays it on a show view.

I am passing the ID of the object, in the redirect_to to the show page. The show page throws an error, and I can't figure out why. Why would the EACH method not be available to the instance variable @questions? (@questions from the show action) - Other answers addressing the same error, aren't relevant in this particular situation. Error follows:

Completed 500 Internal Server Error in 7ms

ActionView::Template::Error (undefined method \`each' for #<Question:0x007fcff50ac950>):  
    1: <div class="flash_notice">flash[:notice]</div>  
    2: <% @questions.each do |q| %>  
    3: <%= q.answer %>  
    4: <% end %>  
  app/views/questions/show.html.erb:2:in   \`_app_views_questions_show_html_erb__4078795064500088796_70265573096080'

  Rendered /Users/iMR-CEO/.rvm/gems/ruby-2.1.2/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.2ms)  
  Rendered /Users/iMR-CEO/.rvm/gems/ruby-2.1.2/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.1ms)  
  Rendered /Users/iMR-CEO/.rvm/gems/ruby-2.1.2/gems/actionpack-4.1.4/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (12.6ms)

Questions Controller:

class QuestionsController < ApplicationController
def index
   @questions = Question.all
end

def new
  @question = Question.new
   @ques1 = "What is the most important business development task you can focus on right      now?"
end

def edit
   @question = Question.find(params[:id])
end



def show
   @questions = Question.find(params[:id])

end

def update
@question = Question.find(params[:id])
if @question.update_attributes(question_params)
    flash[:notice] = 'message'
    redirect_to(:controller => 'home', :action => 'index')
else
  render("edit")
end
end

def create
@question = Question.new(question_params)
if @question.save
  flash[:notice] = 'Answer Stored.'
    redirect_to(:action => 'show', :id => @question.id)

else 
  redirect_to(:action => 'index')
end
end

def delete
@question = Question.find(params[:id])
end

def destroy
@question = Question.find(params[:id]).destroy
flash[:notice] = "Deleted Action - Nice job"
redirect_to(:action => 'new')
end

private
def question_params
params.require(:question).permit(:answer, :question_id)
end
end

Show View:

<div class="flash_notice">flash[:notice]</div>
<% @questions.each do |q| %>
<%= q.answer %>
<% end %>

Routes (in case necessary)

Rails.application.routes.draw do

#get 'home/index'

#get 'home/edit'

#get 'home/delete'

#get 'home/show'

root 'home#index'

#get 'index' => 'questions#index'

#get 'questions/edit'

#get 'new' => 'questions#new'

#get 'questions/delete'

#post 'questions/destroy'

#get 'questions/show'

#post 'create' => 'questions#create'



match ':controller(/:action(/:id))', :via => [:get, :post]

New View:

<%= form_for(@question, :url => {action: "create"}) do |f| %>
<%= f.label(:question, "Question:") %></br>
<%= @ques1 %></br></br>
<%= f.label(:question, "Answer Below") %></br>
<%= f.text_area(:answer) %></br>


<%= f.submit "Answer" %>

<% end %>
</br>

<div align="center"><%= link_to("Home", :action => 'index') %></div>

Upvotes: 0

Views: 218

Answers (5)

Gowri
Gowri

Reputation: 1856

Try this:

Show View:

<div class="flash_notice"><%= flash[:notice] %></div>
<%= @questions.answer %>

Upvotes: 1

Kishore Mohan
Kishore Mohan

Reputation: 1060

In your controller show action @questions variable as an Array-like object, but not an array. When you used that @questions.each in show view page it iterates @questions object key and value pair. Change you code like this:

Question controller

def show
  @question = Question.find(params[:id])
end

Show View:

<div class="flash_notice">flash[:notice]</div>    
  <%= @question.answer %>

Upvotes: 1

scottxu
scottxu

Reputation: 933

change your anction like this:

 def show

@questions = Question.find(params[:id])

 @question = Question.find(params[:id])
end

show view:

<div class="flash_notice">flash[:notice]</div>
<%= @question.answer %>

Upvotes: 1

Pete
Pete

Reputation: 2246

The @questions variable in the show action contains a single Question object and not an Array. The find method in ActiveRecord will return a single entity or raise an exception if no match is found.

This is different to the .all() method in ActiveRecord (e.g in the index action) which returns an Array of Questions or an empty array if none are found.

As the each method belongs to the Array class, the exception is raised when the code tries to call each on a Question object and not an Array object.

Upvotes: 0

Ryan Bigg
Ryan Bigg

Reputation: 107718

In your show view you're attempting to treat the @questions variable as an Array-like object, but it's not an array. You probably just want to do this:

<%= @question.answer %>

As well as defining the show action in your controller like this:

def show
  @question = Question.find(params[:id])
end

Upvotes: 1

Related Questions