IDs getting mixed up in URL

江枫思渺然 提交于 2020-01-26 04:18:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!