简体   繁体   中英

Rails: How to pass instance variables from a controller to render partial

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`

错误

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

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM