ID在网址中混淆了

时间:2012-11-17 19:55:46

标签: ruby-on-rails ruby ruby-on-rails-3

所以我对Ruby on Rails相对较新,正在建立一个项目管理系统,用于使用该语言在我的大学进行独立研究。到目前为止,我创建了:

  • 用户可以创建多个项目的区域(http://i.imgur.com/pXOBg.png)
  • 并且在每个项目中,用户可以创建多个待办事项列表(http://i.imgur.com/FT3no.png
  • 在每个待办事项列表中,用户可以创建多个任务,可以标记为完成/不完整(http://i.imgur.com/DMdcN.png)

所有内容都通过SQLite DB中的外键相关,并且工作相对较好,除了我添加任务时。虽然任务 已添加到待办事项列表中,但我被重定向到错误的URL。我创建了与我的项目管理系统分开的待办事项列表应用程序,只是为了看看我如何创建它以及重定向和一切工作都很好,但是将它实现到我的项目中已经证明有点麻烦。

以下是遇到的问题:http://i.imgur.com/Axuf2.jpg。 URL中的链接应为 http:// localhost:3000 / projects / 2 / lists / 15 ,因此ID会混淆。显示的内容是 http:// localhost:3000 / projects / 15 / lists / 14 其中15是列表的ID,而不是项目的ID,14是任务的ID,而不是名单。

我认为问题出在我的 tasks_controller.rb 中,其中包含以下内容:

class TasksController < ApplicationController

  attr_accessor :completed
  before_filter :find_list
  respond_to :html, :xml, :js

  def create
    @task = @list.tasks.new(params[:task])
    if @task.save
      flash[:notice] = "Task saved"
      redirect_to project_list_url(@list)
    else
      flash[:error] = "Task could not be saved"
      redirect_to project_list_url(@list)
    end
  end

  def complete
    @task = @list.tasks.find(params[:id])
    @task.completed = true
    @task.save
    redirect_to project_list_url(@list)
  end

  def incomplete 
    @task = @list.tasks.find(params[:id])
    @task.completed = false
    @task.save
    redirect_to project_list_url(@list)
  end

  def destroy
    @task = @list.tasks.find(params[:id])
    if @task.destroy
      flash[:notice] = "Task deleted"
      redirect_to project_list_url
    else
      flash[:error] = "Could not delete task"
      redirect_to project_list_url
    end
  end

  private 

  def find_list
    @list = List.find(params[:list_id])
  end

end

我认为问题出现在以下$link redirect_to project_list_url(@list)上,因为我认为它应该是$link redirect_to project_list_url(@project, @list)。但每次我添加:

@project = Project.find(params[:project_id])

对于我的代码,待办事项任务不会从完成移动到不完整,反之亦然。

以下是待办事项列表视图中的代码:

<h3>Stuff to do</h3>
<ul>
  <% @list.tasks.incomplete.each do |task| %>
    <li><%= task.description %> <%= button_to "Complete", complete_task_path(@list.id,task.id) %></li>
  <% end %>
</ul> 

<h3>Stuff I've Done</h3>
<ul>
  <% @list.tasks.completed.each do |task| %>
    <strike><li><%= task.description %></strike> <%= button_to "Incomplete", incomplete_task_path(@list.id,task.id) %></li>
  <% end %>
</ul> 

<hr />

<%= form_for [@project, @list, @task] do |form| %>
  <p><%= form.text_field :description %> <%= form.submit %></p>

最后,我们快速浏览一下 routes.rb

root :to => 'home#index'

devise_for :users

resources :projects do 
  resources :messages
  resources :lists do
    resources :tasks
  end
end

match 'lists/:list_id/tasks/:id/complete' => 'tasks#complete', :as => :complete_task
match 'lists/:list_id/tasks/:id/incomplete' => 'tasks#incomplete', :as => :incomplete_task

因此,ID会在URL中混合,并且每当我编辑列表时它们也会这样做(尽管我想我是否可以修复它以完成我可以为所有事情修复它的任务)。

非常感谢任何看过这个并给我提供帮助的人,我非常感谢您的所有时间。如果您需要查看任何其他控制器,模型或视图(项目,列表,任务)或项目中的任何内容,我将非常乐意与您分享。

2 个答案:

答案 0 :(得分:1)

project_list_url(@list):此路由助手有两个参数:项目和列表。尝试添加项目(或只是项目ID):

redirect_to project_list_url(@list.project_id, @list)

答案 1 :(得分:0)

初看起来我认为将资源嵌套在3级以上是不恰当的。您可以在此Ruby on Rails Guide中阅读更多内容。但是,让你的生活更加轻松的是何塞·瓦利姆的masterpiece inherited_resources。它解决了嵌套资源的许多问题。

您的控制器中似乎错过了一件更重要的事情:新动作。无论您是否创建了操作,新数据库记录都依赖于“新”操作。

def new
 @list = List.find(params[:list_id])
 @task = Task.new
end

def create
 @list = List.find(params[:list_id])
 @task = @list.build(params[:task])
  if @task.save
   # success
  else
   # fail
  end
end

这是创建关联背后的基本逻辑。

编辑:我在“新”动作中看到了我的错误:而不是@task = Task.new它应该是'@task = @ list.tasks.new'。