在他的tutorial之后,Static-Pages Controller的主页呈现了partial_form:
<%= render 'shared/micropost_form' %>
StaticPagesController.rb
def home
@micropost = current_user.microposts.build #for the form_form
@feed_items = current_user.feed.paginate(page: params[:page])
end
然后,在MicropostController.rb中,声明了部分micropost_form的操作:
class MicropostsController < ApplicationController
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
flash[:success] = "Micropost created!"
redirect_to root_url
else
@feed_items = []
render 'static_pages/home'
end
end
end
请注意,如果micropost_form成功,它会重定向static_pages的索引视图,但是,如果失败,它会呈现static_pages主视图(这也会保留表单中的参数,因此用户不必将所有数据写入其中) ,但是,它需要初始化static_pages的主控制器实例变量(即feed_items)。
现在,假设StaticPages Controller的home有一长串复杂实例变量,MicropostController如何渲染(在失败时保存表单数据)static_pages / home而不创建那么多实例变量?
注意:此问题与my previous one有关,但我之前想要理解这个基本示例。
答案 0 :(得分:1)
MicropostController如何呈现(在失败时保持表单数据) static_pages / home没有创建那么多实例变量?
简单的答案是它不能。在Rails中,你无法在内部重定向 - 这是一种有意的设计。这意味着一旦路由器匹配请求,您就无法将请求“修补”到StaticPagesController#home
。
因此,为了让MicropostsController
呈现static_pages/home
,它需要执行与StaticPagesController
相同的工作。
但是,如果设置实例变量很难或者你想避免重复,那么一个好的技术是使用模块来提取共享功能。
# app/controllers/concerns/feedable.rb
module Feedable
protected
def set_feed_items!
@feed_items = FeedItem.includes(:comments).all
end
end
class StaticPagesController < ActiveRecord::Base
include Feedable
# ...
before_action :set_feed_items!, only: [:home]
end
class MicropostsController < ApplicationController
include Feedable
# ...
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
flash[:success] = "Micropost created!"
redirect_to root_url
else
set_feed_items!
render 'static_pages/home'
end
end
end
答案 1 :(得分:0)
如果你的from引用了实例变量,那么无论是在home
方法还是create
方法中,你都需要在渲染表单时初始化实例变量。
这是Sandi Metz提出的“开发者规则”第4条的原因之一
控制器只能实例化一个对象。因此,视图只能 知道一个实例变量,视图应该只发送消息 到那个对象
请参阅此处查看所有规则...... https://robots.thoughtbot.com/sandi-metz-rules-for-developers