1

I am having trouble passing an instance variable (@article) from a controller (articles_controller.rb) to a partial render (_form.html.erb) in Ruby.

Here is the error from being sent back:

`undefined method `errors' for nil:NilClass`

Error

articles_controller.rb:

class ArticlesController < ApplicationController
  def new 
  end
  
  def create
    @article = Article.new(article_params)   
    if @article.save
      redirect_to @article
    else
      render 'new'
    end
  end
  
  def update
    @article = Article.find(params[:id])
    
    if @article.update(article_params)
      redirect_to @article
    else
      render 'edit', :article => @article
    end
  end
  
  def show
    @article = Article.find(params[:id])  
  end
  
  def index 
    @articles = Article.all    
  end
  
  private
    def article_params
      params.require(:article).permit(:title, :text)
    end
end

new.html.erb

<h1>New Article</h1>

<%= form_for :article, url: articles_path do |f|%>
    <%= render partial: "form", :locals => {:article => @article} %>
<% end %>

<% link_to 'Back', articles_path %>

_form.html.erb

<% if @article.errors.any? %>
<div id="error_explanation">
    <h2>
        <%= pluralize(@article.errors.count, "error") %> prohibited this 
article from being saved:           
        </h2>
        <ul>
            <% @article.errors.full_messeages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
        </ul>
    </div>
<% end %>   

<p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>  
</p>

<p>
    <%= f.label :text %><br />
    <%= f.text_area :text %>        
</p>

<p>
    <%= f.submit %>     
</p>

Any help would be appreciated

4
  • 1
    Have you initialized the @article in your new method? Commented Oct 13, 2016 at 7:21
  • Have you tried my answer below? Commented Oct 13, 2016 at 7:36
  • araratan, I tried it but it didn't seem to do the trick. Shabini Rajadas, was right, I forgot to initialize @article in new, I only initialized it in create Commented Oct 13, 2016 at 7:41
  • @aratatan, thank, I understand now. You pass the controller's instance variable as a local variable. Everything is working now Commented Oct 13, 2016 at 7:45

3 Answers 3

1
def new 
  @article = Article.new
end  




<%= render partial: "form", collection: @article %>

or even

<%= form_for @article do |f|%>
    <%= render 'form' %>
<% end %>

depends on your needs

Sign up to request clarification or add additional context in comments.

Comments

1

I had this challenge when working on a Rails 6 application.

I wanted to use an instance variable in a partial (app/views/shared/_header.html.erb) that was defined in a different controller (app/controllers/categories_controller.rb).

Here's how I did it:

The instance variable that I wanted to use is @categories which is defined as:

# app/controllers/categories_controller.rb

class CategoriesController < ApplicationController

  def index
    @categories = Category.all
  end
  .
  .
  .
end

Firstly, I rendered the app/views/shared/_header.html.erb partial in the app/views/layouts/application.html.erb and passed the @categories instance variable into it this way:

<%= render partial: '/shared/header', locals: { categories: @categories } %>

And then I used the instance variable in the partial this way:

# app/views/shared/_header.html.erb

<% @categories.each do |category| %>
  <%= link_to category do %>
    <%= category.name %>
  <% end %>
<% end %>

However, this will require a controller action that sets a @categories instance variable for every controller views that will use the partial.

If you want to make variables globally available in your controllers and views, this could help: Rails: Set a common or global instance variable across several controller actions

That's all.

I hope this helps

Comments

0

You should do like this, removing @. You are passing it to local variable article so you could access it with article not @article:

<% if article.errors.any? %>
<div id="error_explanation">
    <h2>
        <%= pluralize(article.errors.count, "error") %> prohibited this 
article from being saved:           
        </h2>
        <ul>
            <% article.errors.full_messeages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
        </ul>
    </div>
<% end %>   

<p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>  
</p>

<p>
    <%= f.label :text %><br />
    <%= f.text_area :text %>        
</p>

<p>
    <%= f.submit %>     
</p>

For more info, please take a look at passing-local-variables

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.