问题
So I am relatively new to Ruby on Rails and am building a project management system for an independent study at my University using the language. So far I have created:
- an an area where a user can create a multiple projects(http://i.imgur.com/pXOBg.png)
- and in each project a user can create multple to-do lists (http://i.imgur.com/FT3no.png)
- within each to-do list, a user can create multiple tasks which can be marked as complete/incomplete (http://i.imgur.com/DMdcN.png)
Everything's related via foreign keys in the SQLite DB, and is working relatively fine, except that when I add a task. Although the task does get added to the to-do list, I get redirected to an incorrect URL. I created the to-do list app separate from my project management system just to see how I could create it and the redirecting and everything worked just fine, but implementing it into my project has proved somewhat troublesome.
Here is the problem that am running into: http://i.imgur.com/Axuf2.jpg. The link in the URL should be http://localhost:3000/projects/2/lists/15, so the IDs are getting mixed up. What's being displayed is http://localhost:3000/projects/15/lists/14 where 15 is the ID of the list, not the project, and 14 is the ID of the task, not the list.
I believe the problem lies within my tasks_controller.rb, which contains the following:
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
I think that the problem arises on the following $link redirect_to project_list_url(@list)
because I believe that it should be $link redirect_to project_list_url(@project, @list)
. But everytime I add:
@project = Project.find(params[:project_id])
To my code, the to-do tasks won't move from completed to incomplete or vice versa.
Here is the code in my to-do list view:
<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>
Lastly, here's a quick look at my 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
So the IDs are mixed up in the URL, and they do this whenever I edit a list as well (although I figured if I could fix it for the tasks that I could fix it for everything).
Thanks a lot to anybody who takes a look at this and offers me help, I really appreciate all of your time. If you need a look at any other controllers, models or views (projects, lists, tasks) or anything from my project, I would be more than happy to share it.
回答1:
project_list_url(@list)
: this routing helper takes two parameters: a project and a list. Try adding the project (or just the project id):
redirect_to project_list_url(@list.project_id, @list)
回答2:
At a first sight I think it is not proper to nest resources deeper than 3 levels . You can read more in this Ruby on Rails Guide . But what will make your life easier for sure is Jose Valim's masterpiece inherited_resources. It solves a lot of problems with nested resources .
It seems you've missed one more important thing in your controller : new action . No matter you have create action , you new database record depends on the 'new' action .
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
That's the basic logic behind creating associations .
EDITED : I see my mistake in the 'new' action : instead of @task = Task.new it should be '@task = @list.tasks.new' .
来源:https://stackoverflow.com/questions/13434244/ids-getting-mixed-up-in-url