ruby-on-rails - 一个 View 中的多个 Controller (Ruby on Rails MVC)

标签 ruby-on-rails controller render parameters

嘿伙计们,我需要你们宝贵的帮助。在 Ruby on Rails tutorial ,在第10章,作者在一个 View 中有2个 Controller 。我构建了一个类似的应用程序,其中一个 View 中也有 2 个 Controller ,但是,当我渲染属于第二个 Controller 的方法时,从第一个开始我就遇到了参数问题。 (在教程中作者没有在其他 Controller 的操作中使用任何参数)

更具体地说,我有 2 个 Controller :UsersController 和 MicropostsController。另外,在 Users 的 show.html.haml 页面中,我使用两个 Controller :UsersController 用于显示用户的微帖子和 MicropostsController 以允许用户创建新的微帖子。

MicropostsController 内部:

def create
  @micropost = current_user.microposts.build(params[:micropost])
  if @micropost.save
    flash[:success] = "Micropost created!"
    redirect_to user_path(current_user)
  else
    #render text: renderActionInOtherController(UsersController,:show, {:id => 1})
    @user = User.find(current_user)
    @microposts = @user.microposts.paginate(page: params[:page])
    render 'users/show'
  end
end

用户 Controller 内部

def show
  @user = User.find(params[:id])
  @microposts = @user.microposts.paginate(page: params[:page])
  @micropost = current_user.microposts.build if signed_in?
end

在app/views/users/show.html.haml中

- provide(:title, @user.name)
.users_page
  .row
    %aside.span4
      - if !signed_in?
        %section
          %h1
            = gravatar_for @user
            = @user.name
      - else
        %section
          = render 'shared/user_info'
        %section
          = render 'shared/micropost_form'

    .span8
      - if @user.microposts.any?
        %h3 Microposts (#{@user.microposts.count})
        %ol.microposts
          = render @microposts
        = will_paginate @microposts

基本上我的问题总结如下:

1) 在 1 个 View 中拥有多个 Controller 是一个好习惯吗?我在网上找到了相互矛盾的答案。 (实际上,我什至不确定这段代码是否仍然是 RESTful)

2)如果 1 是肯定的(或者至少这不是一个坏习惯),我可以以更有效的方式实现同​​样的事情吗?因为在我看来,每次我从另一个 Controller 渲染 Action 时,我都必须重新定义变量。

3) 我找到了 similar stackoverflow 中的一个主题,其中有人建议使用这种方法(由于我是 RoR 新手,所以我不明白它到底做了什么)。

def renderActionInOtherController(controller,action,params)
  controller.class_eval{
    def params=(params); @params = params end
    def params; @params end
  }
  c = controller.new
  c.request = @_request
  c.response = @_response
  c.params = params
  c.send(action)
  c.response.body
end

如果我在 MicropostsController 中使用此版本的创建操作,

def create
  @micropost = current_user.microposts.build(params[:micropost])
  if @micropost.save
    flash[:success] = "Micropost created!"
    redirect_to user_path(current_user)
  else
    render text: renderActionInOtherController(UsersController,:show, {:id => 1})
    #@user = User.find(current_user)
    #@microposts = @user.microposts.paginate(page: params[:page])
    #render 'users/show'
  end
end

当我点击发布按钮时,浏览器中什么也没有得到。此外,当我尝试查看 users/1 页面时,出现以下错误(!!):

undefined method `[]' for nil:NilClass

任何帮助都非常有值(value)!如果您需要任何其他信息,请告诉我!

最佳答案

  1. 从技术上讲,这个术语有些令人困惑。默认情况下, Controller 中的每个方法都对应一个名称相似的 View 文件,因此最好将问题表述为“渲染非默认 View 的 View 是否是一种好的做法?”答案当然是,这取决于情况。这是一种常用于干燥 Controller 代码的技术,如果它能带来好处,在您的应用程序中,我肯定会使用它。其实Rails中默认资源脚手架生成的 Controller 代码uses itcreateupdate 方法中。我认为您可以认为 Rails 核心中的任何内容即使不是最佳实践,至少也是在合理范围内的。

  2. 话虽如此,可能还有改进的机会。处理相同事情的常见方法是将创建和更新请求路由到相同的 Controller 操作并使用相同的 Controller View 。如果这不可行,至少可以保证您不需要重新定义变量。来自official documentation :

Using render with :action is a frequent source of confusion for Rails newcomers. The specified action is used to determine which view to render, but Rails does not run any of the code for that action in the controller. Any instance variables that you require in the view must be set up in the current action before calling render.

  1. 你不应该这样做......在这种情况下,或者在我能想到的任何其他情况下都不需要。任何时候你在 Rails 中看到像这样的 super hacky 的东西都表明某些事情可能不太正确,并且可能有更好的方法来处理同样的事情。

奖励:如果您需要去某个已经负责设置自身的地方,并且您不需要访问任何范围内的变量,那么重定向可能是更好的选择。这样,您就不需要在多个地方重新描述 Controller 逻辑。以下是您发布的代码的示例:

    # inefficient and not DRY
    @user = User.find(current_user)
    @microposts = @user.microposts.paginate(page: params[:page])
    render 'users/show'

    # does the same thing as above (in this case)
    redirect_to users_path

关于ruby-on-rails - 一个 View 中的多个 Controller (Ruby on Rails MVC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13277047/

相关文章:

ruby-on-rails - 自动将文件部署到 Amazon S3?

ruby-on-rails - Ruby DateTime.new 困惑

ruby-on-rails - RuntimeError : Declare either attr_protected or attr_accessible for User, 但不是两者

javascript - AngularJs:对 Controller 的实现存疑

reactjs - reduxForm - 更新后初始值不适用

mysql - Rails 如何检查 sql 查询生成的内容

cakephp - cakephp 中的 anchor 标记

javascript - 从控制台(Chrome 或 Firefox)访问 Angular Controller

java - 如何创建和渲染 3D 分形?

ruby-on-rails-3 - 在 ruby​​ on rails 中渲染备用 View