原文: http:/redworld.blog.ubuntu.org.cn/2008/03/02/rails20%e7%9a%84%e5%86%85%e5%b5%8c%e8%b5%84%e6%ba%90/
Rails2.0中提供了一套更好的嵌套资源的处理方法(更加形象化)。
比如有两个model:
# app/model/project.rb class Project < ActiveRecord::Base has_many :tasks end # app/model/task.rb class Task < ActiveRecord::Base belongs_to :project end
在migrate中可以用referece类型来表示引用外键,比如在创建task的migrate中
create_table :tasks do |t| ... t.references :project ... end
路由规则定义如下:
# config/routes.rb ActionController::Routing::Routes.draw do |map| map.resources :projects do |project| project.resources :tasks end end
比较好的一个方法调用Task所属Project的方法是用before_filter调用一个方法来设置:
class ArticlesController < ApplicationController before_filter :load_project ... def load_project @project = Project.find params[:project_id] end end
把Controller中的涉及内嵌资源的find和new的调用改一下:
@project.tasks.find #=> 代替原来的Tasks.find @projece.tasks.build #=> 代替原来的Tasks.new
还有把Controller中的redirect_to方法的参数修改一下:
redirect_to([@project, @task])
那在Task的view中应该做如下处理
在生成表单时,传入一个数组给form_for方法:
form_for([@project, @task])
调用Tasks Controller的new方法:?
new_project_task_path # => domain/projects/:id/tasks/new
调用Tasks Controller的show方法:?
link_to 'Show', [@project, @task] # => domain/projects/:id/tasks/:id
调用Tasks Controller的edit方法:?
link_to 'Edit' edit_project_task_path # => domain/projects/:id/tasks/:id/edit
或者
link_to 'Delete', [:edit, @project, @task] # => domain/projects/:id/tasks/:id/edit
调用TasksController的destory方法:
link_to 'Delete', [@project, @task], :confirm => 'Are you sure?', :method => :delete # => domain/projects/:id/tasks/:id
通过这些方法就能让内嵌资源使用时更加优雅,而不用在导向时指定controller和action,再传入父资源和子资源的id。这些 xx_path方法会帮你查找routes.rb的路由定义,然后生成url,当然这一切都是基于Rails2.0提倡的RESTful。
参考文章:
http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial