【问题标题】:Ruby on Rails: how to render a view from same controller but with a different route?Ruby on Rails:如何从同一个控制器渲染视图但使用不同的路由?
【发布时间】:2016-03-25 13:06:24
【问题描述】:

我有一个控制器,farms_controller,用于两条不同的路线,farmsperson_farms;这两条路线使用相同的文件夹作为视图模板(即new_person_farm_pathnew_farm_path 使用相同的模板new.html.erb)。我想分别访问农场注册页面和个人注册内部,其中某些功能是不同的,在某些测试中使用 URL 来显示不同的功能(通过request.env['PATH_INFO'].include? 'person_farms',因为我不知道最好的方法)。

当我在没有来自new_person_farm_path 的必填字段(名称)的情况下提交时,create 函数会为不正确的字段呈现具有不同样式的new_farm_path 页面(使用'twitter-bootstrap-rails' gem)。我希望它使用相同的模板文件但不同的路由(不同的 URL)来呈现 new_person_farm_path 页面。我尝试使用redirect_to,它在正确的 URL 中显示页面,但在错误的字段中没有样式。

但是,我在Rails documentation for rendering 中看到的所有指令都在渲染特定文件,但这不是我需要的。我有一种感觉,这不是“Rails 方式”,但我是 RoR 的初学者,这是一个正在重写为 Rails 的遗留系统,所以我现在无法更正数据库逻辑。

那么,有没有办法从同一个控制器渲染一个视图,但使用不同的路由?


我的代码:

def create
  @farm = Farm.new(farm_params)
  respond_to do |format|
    if @farm.save
      # Param sent by the page to test if I'm in a person_farms page
      # instead of a farms page because the request.env test doesn't work here.
      # I feel that this is not the correct way to do that, but I can leave the correct way to another question.
      # However, if someone has a suggestion a comment would be appreciated.
      if params[:is_person_farm_page]
        format.html { redirect_to @person_farm_path(@farm), notice: 'Farm saved' }
        format.json { render :show, status: :created, location: @farm }
      else
        format.html { redirect_to @farm, notice: 'Farm saved' }
        format.json { render :show, status: :created, location: @farm }
      end
    else
      #This is the point where I want to redirect to new_person_farm_path
      #I would need to test using the params[:is_person_farm_page] above
      format.html { render :new }
      format.json { render json: @farm.errors, status: :unprocessable_entity }
    end
  end
end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4


    【解决方案1】:

    在路径中发送参数如:

    new_person_farm_path(param_1: 'my param')
    

    然后在控制器中,您可以通过以下方式访问该值:

    params[:param_1]
    

    并将其作为实例变量或(如果您正在使用)视图对象传递给您的视图:

    @show_some_part = params[:param_1].present? # This can be a boolean or something else
    

    现在在您看来,您可以要求该值

    <%= something if @show_some_part %>
    

    【讨论】:

    • 所以,我应该使用相同的路由(以及相同的 URL),而不是使用两个不同的路由,但是每次我从控制器调用路径时,我都可以传递一个参数,所以它会知道我在 person_farms 页面或农场页面,对吗?
    【解决方案2】:

    为了解决我的具体问题(重定向到正确的 new 页面,但带有错误字段),我做了这个解决方案(如果你从一开始就这样做,可能不是最好的,但我已经有很多功能在工作,并且我想将 person_farm_pathfarm_path 保留为不同的 URL):

    在我的控制器中,我使用了该线程的第一个答案:Rails: I cant pass a validation error in a redirect,因此我将此代码插入到 create 操作中:

    if @farm.save
      ... #the same code in my question
    else
      if params[:is_person_farm_page]
        #pass the errors messages via flash, "imploding" the array of errors into a string
        format.html { redirect_to new_person_farm_path, :flash => { :error => flash_errors = @farm.errors.full_messages.join(',')}}
        format.json { render json: @farm.errors, status: :unprocessable_entity }
      else
        format.html { render :new }
        format.json { render json: @farm.errors, status: :unprocessable_entity }
      end
    end
    

    现在我可以通过重定向操作而不是渲染操作来传递错误。 然后,在form.html.erb 中,我只需要“分解”新数组中发送的字符串:

    <% errors_sent_via_flask = flash[:error] ? flash[:error].split(",") : [] %>
    

    为了查看我能得到的所有errors_message,我使用了&lt;%= errors_sent_via_flask .inspect %&gt;(这与页面中的所有数组成员相呼应)并模拟了错误情况并提交了表单。例如,缺少名称字段的错误消息类似于“农场名称不能为空”。

    现在我可以使用页面中的errors_sent_via_flask.include? "Farm name can't be blank" 检查“农场名称不能为空”错误是否发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多