繁体   English   中英

Michael Hartl Rails教程4,micropost部分和实例变量

[英]Michael Hartl Rails Tutorial 4, micropost Partial and instance variables

按照他的教程 ,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的主目录包含一长串复杂的实例变量,那么MicropostController如何在不创建那么多实例变量的情况下呈现(以在失败时保留表单数据)static_pages / home?

注意:这个问题与我之前的问题有关,但是我想在此之前理解这个基本示例。

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

如果您的from引用实例变量,那么无论您是在home方法还是在create方法中,您都需要在渲染表单时初始化实例变量。

这是Sandi Metz提出她的开发人员规则第4条的原因之一

控制器只能实例化一个对象。 因此,视图只能知道一个实例变量,而视图只能将消息发送到该对象

有关所有规则,请参见此处... https://robots.thoughtbot.com/sandi-metz-rules-for-developers

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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