【问题标题】:Routes in Rails3 - Controller and routes for 2 post functionsRails3 中的路由 - 2 个 post 函数的控制器和路由
【发布时间】:2011-03-22 18:10:15
【问题描述】:

我正在尝试在 rails 3 中编写一个应用程序,但在确定我希望用户进行的测试的路线和控制器时遇到了一些麻烦。此应用的基本要求是:

  1. 用户、测试和问题都在不同的模型中。
  2. 一个用户有_many测试。一个测试有_many Questions
  3. 在 user_profile 页面上提供指向 /test/new 的链接以创建测试记录。
  4. 在 /test/new 上提供指向 /test/:id/part1 的链接(其中 :id 是 test_id),以便用户可以完成测试的第一部分。问题将从数据库中检索并呈现在此页面上。
  5. 在 /test/:id/part1 上提供指向 /test/:id/part2 的链接,以便用户可以完成测试的第二部分。同样,问题是从数据库中检索出来的。
  6. 在 /test/:id/part2 上提供一个链接以提交测试并返回到用户的个人资料。

我已经完成了模型,甚至通过了他们的测试,所以我想我已经完成了第 1 部分和第 2 部分。

用户.rb

Class User < ActiveRecord::Base
  has_many :tests
end

test.rb

Class Test < ActiveRecord::Base
  belongs_to :user
  has_many :questions
end

问题.rb

Class Question < ActiveRecrod::Base
  belongs_to :test
end

当我尝试使用路由和控制器将这些模型放在一起时,我的问题就开始了。

routes.rb

resources :users

resources :tests do
  member do
    post 'part1'
    post 'part2'
  end
end

用户/show.html.erb

<%= link_to "Start The Test", new_test_path %>

测试/new.html.erb

<%= link_to "Part 1", part1_test_path(@test) %>

tests_controler.rb

class TestsController < ApplicationController
  def new
    @test = Test.new(current_user)
  end

  def part1
    # still just a stub
  end
end

当我点击链接参加第 1 部分测试时遇到此错误:

No route matches {:action=>"part1", :controller=>"tests", :id=>#<Test id: nil, taken_at: nil, user_id: nil, created_at: nil, updated_at: nil>}

对此的任何帮助将不胜感激。

【问题讨论】:

    标签: ruby-on-rails-3 routes


    【解决方案1】:

    通过定义路由的成员,它期望一个存在的测试,即。一个已保存并具有 id。

    例如

    part1_test_path = /test/123/part1
    

    你需要的是一个收集路线。

    resources :tests do
      collection do
        post 'part1'
      end
      member do
        post 'part2'
      end
    end
    

    例如

    part1_test_path = /test/part1
    

    编辑

    建议的解决方案:

    resources :test, :path_names => { :new => 'part_1', :edit => 'part_2' } *1
    
    def new 
      @test = Test.new
    
    #new view
    form_for @test do
      ...
    
    def create
      @test = Test.new params[:test]
      if @test.save
        redirect_to edit_test_path @test
    
    def edit
      @test = Test.find params[:id]
    
    #edit view
    form_for @test do
    
    def update
      @test = Test.find params[:id]
      if @test.update_attributes params[:test]
        redirect_to test_path @test 
    
    
    def show # test results
      @test = Test.find params[:id]
      if @test.incomplete *2
        redirect_to edit_test_path @test
    

    *1 见rails guide on routing。这会给你这样的网址

    测试/第 1 部分 测试/123/part2

    您应该将所有验证都放入模型中;您对测试数据的要求。需要条件验证,具体取决于它是否是 new_record?或者不是,即如果你在第 1 部分或第 2 部分。

    *2 向您的模型添加一个检查测试完整性的方法。

    def incomplete
      self.some_test_field.blank?
    

    如果你有什么不明白的地方请告诉我。

    【讨论】:

    • 感谢马克的回答。但是,这个解决方案不会为 part1 和 part1 提供不同的路线(即 part1_test_path = /test/part1 和 part2_test_path = /test/123/part2)吗?我想在这些之间保持一致,以便代码库更易于维护。使用您对成员期望存在测试的洞察力,我决定在 /test/new 页面上调用创建控制器,然后尝试重定向到第 1 部分。看起来很有希望。
    • 就我个人而言,我会采用我的方法,但您的方法同样有效。如果您还没有,您可能想查看这些复杂表单上的 railscasts 剧集。 railscasts.com/episodes/73 它们适用于 rails 2,但除了一些适用于 3 的小语法。
    • 谢谢马克。你的方法有什么更符合“铁路之路”的地方吗?我是 Rails 新手,我想尽可能地遵循规范风格,因为我计划将此应用程序交给其他开发人员,所以我试图尽可能地遵循 - 并学习 - 惯例。
    • 我将根据我建议您执行的操作以及我认为更符合惯例的操作来编辑我的答案。 :)
    • 感谢您提供了这样一个很好的例子。我的具体案例与此略有不同,但我真的很喜欢您将所有内容保留在预期的新、创建、编辑、更新和显示方法中。
    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 2016-04-21
    • 2023-03-22
    • 2011-10-12
    • 2016-07-12
    • 1970-01-01
    • 2015-12-29
    相关资源
    最近更新 更多