我对Ruby on Rails很新,在项目中使用4.1版。
我对嵌套资源在rails中的工作方式感到有点困惑。也许有人可以帮忙。
我正在建立一个任务系统作为一个学习项目。
我的网站拥有属于他们的任务。查看任务时,我可以这样做:
resources :websites do
resources :tasks
end
一个链接可以让我完成我的任务,只需要http://myapp.com/websites/2/tasks/3
这样的网址<%= link_to 'Show', website_task_path(website,task) %>
我注意到的是,我可以将网址中的网站ID更改为任何内容 - http://myapp.com/websites/what-the-hell-is-going-on-here/tasks/1 - 与其他链接的工作方式相同。或者我也可以在网址中使用不同的网站ID访问该任务。
所以问题是,Rails是否应该默认对这条信息做任何事情?如果我想确保您使用参数中的正确父资源访问任务,是否由我决定?
答案 0 :(得分:5)
您的任务ID在任务表中是唯一的。只要您想显示,编辑或删除任务,此信息就足够了。您可以通过您的关联轻松获得父母。但是嵌套资源允许您创建新任务。在这种情况下,没有ID集。您需要知道正确的父级才能在您的任务中设置它。
摘自可能的TasksController:
class TasksController < ApplicationController
before_action :set_website, only: [:create]
def create
@website.tasks.create!(task_params)
end
private
def set_website
@website = Website.find(params[:website_id])
end
def task_params
params.require(:task).permit(:title, :text)
end
end
生成的嵌套路由:
# Routes without :task_id - Parent matters!
website_tasks
GET /websites/:website_id/tasks(.:format) tasks#index
POST /websites/:website_id/tasks(.:format) tasks#create
new_website_task
GET /websites/:website_id/tasks/new(.:format) tasks#new
# Routes with :task_id - Parent redundant.
edit_website_task
GET /websites/:website_id/tasks/:id/edit(.:format) tasks#edit
website_task
GET /websites/:website_id/tasks/:id(.:format) tasks#show
PATCH /websites/:website_id/tasks/:id(.:format) tasks#update
PUT /websites/:website_id/tasks/:id(.:format) tasks#update
DELETE /websites/:website_id/tasks/:id(.:format) tasks#destroy
您可以使用浅嵌套清除冗余website_id中的路由。详细解释了in the Rails docs。
基本上它意味着:
resources :website do
resources :tasks, only: [:index, :new, :create]
end
resources :tasks, only: [:show, :edit, :update, :destroy]
与写作相同:
resources :websites do
resources :tasks, shallow: true
end
可能存在一些完整路径有价值的用例,例如: G。您希望将其提供给搜索引擎,或者您希望该网址更适合读者。
答案 1 :(得分:1)
所以问题是,Rails应该对这件作品做些什么 信息默认情况下?
如果您愿意,可以直接在ULR中对其进行硬编码来更改网站ID,但由于您的控制器负责根据请求动态生成URL,因此无法更新网站ID。
如果我想确保您正在访问该任务,请由我决定 在参数中使用正确的父资源?
是的,您可以通过确保以下内容确保使用正确的父级访问A任务:
has_many :tasks
和任务:belongs_to :website
(例如)如果您想使用网站控制器创建任务,您可能还需要添加accepts_nested_attributes_for :tasks, reject_if: :all_blank, allow_destroy: true
(我不知道你想做什么)@website.tasks.new(task_params)
,以便使用website_id将任务保存在数据库中,这将允许您根据您的关联检索任务或任务只要模型,视图和控制器知道网站和反之亦然的任务,您的路线就会生成并运行。