问题
For example, given a basic controller such as:
class PostsController < ApplicationController
def index
@post = Post.all
end
The instance variable @post
is available in the view posts/index.html.erb
but not the partial posts/_index.html.erb
My primary questions are: Why is this? and How can I define a method for a partial in a controller to for example, pass an instance variable?
On a more specific note:
I ask this because the way I am rendering data in a separate, primary view welcome/index.html.erb
is via this posts partial. I have gotten around this limitation by directly calling the model with Post.all
in the posts/_index.html.erb
partial, but as far as I understand this ignores MVC architecture and severely limits me from developing more complex methods, unless I really break convention and write them into the view (which I assume may work but is poor design).
Currently, @post is passing a nil to the partial symbol :post in welcome/index.html.erb
Clearly I'm missing something, so any insight would be greatly appreciated!
Thank you
Relevant files:
views/
posts/
_index.html.erb
_new.html.erb
show.html.erb
welcome/
index.html.erb
controllers/
posts_controller.rb
welcome_controller.rb
posts/_index.html.erb
<% post.reverse.each do |post| %>
<div class="panel panel-default">
<div class="panel-body">
<%= post.text %>
</div>
</div>
<% end %>
posts/_new.html.erb
<%= form_for :post, url: posts_path do |f| %>
<p id="post_box">
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
posts/show.html.erb
<%= @post.text %>
welcome/index.html.erb relevant portions (partials)
<%= render partial: "posts/index", locals: {post: @post} %>
<%= render partial: "posts/new" %>
controllers/posts_controller.rb
class PostsController < ApplicationController
def new
end
def create
@post = Post.new(post_params)
@post.save
redirect_to '/'
end
def show
@post = Post.find(params[:id])
end
def index
@post = Post.all
end
private
def post_params
params.require(:post).permit(:text)
end
end
controllers/welcome_controller.rb
class WelcomeController < ApplicationController
end
回答1:
You're right that you're breaking MVC conventions by calling controller-level object lookups in your view.
When you call the render action on the partial you have a variety of arguments to send, one of which is a locals
hash that takes a variable you want to pass directly into your partial.
It looks like this:
<%= render partial: "something", locals: {posts: @posts} %>
The rails guides are a great resource on the topic. More on that here.
来源:https://stackoverflow.com/questions/28184011/why-arent-instance-variables-defined-in-a-controllers-methods-available-in-the