Как установить значение параметра scoped в form_with - PullRequest
2 голосов
/ 15 апреля 2020

Я выполняю рефакторинг маршрутов моего приложения, чтобы обратиться к эмпирическому правилу , потому что мои маршруты очень длинные.

Представьте, что у меня есть следующие модели

class Company < ApplicationRecord
  has_many :projects
  has_many :users
  ...
end

class Project < ApplicationRecord
  belongs_to :company
  has_many :jobs
  ...
end
...

и мои маршруты выглядят как

Rails.application.routes.draw do
  ...
  resources :companies do
    resources :projects do
      resources :jobs
    end
  end
end

После того, как пользователь вошел в систему, я установил @current_user и компании, к которым он имеет доступ - @current_user.companies. При таком подходе я избегаю попадания в базу данных, когда пользователи изменяют URL-адрес для доступа к неавторизованным ресурсам. Например, когда пользователь редактирует задание:

/companies/1/projects/30/jobs/20/edit

class JobsController < ApplicationController 
  def edit
    @project = @company.projects.find(params[:project_id]) 
    @job = @project.jobs.find(params[:job_id])
    ...
  end
  ...
end

Я следовал примеру из руководств и добавил область действия с префиксным именованным параметром , чтобы сократить один уровень вложенных ресурсов.

scope ':company_id' do
  resources :projects do
    resources :jobs
  end
end

Пока все хорошо, я успешно сократил свои URL с

/companies/1/projects/30/jobs/20/edit
edit_company_project_job_path(@company, @project, @job)

до

/1/projects/30/jobs/20/edit
edit_project_job_path(@company, @project, @job)

Но затем я сломал свой form_with model: [@company, @project, @job], потому что он не может сделать вывод именованный параметр с префиксом - :compay_id, даже если я его укажу @company.id.

Единственное решение, с которым я пришел, - снова установить именованный маршрут

scope ':company_id' as: 'company' do
  resources :projects do
    resources :jobs
  end
end

Разве это не такой же как раньше? Я только что закорочил URL /1/projects/30/jobs/20/edit, но путь вернулся к исходному edit_company_project_job_path(@company, @project, @job). Я что-то пропустил? Я хотел бы знать, как ты это делаешь

1 Ответ

3 голосов
/ 15 апреля 2020

Вы действительно неправильно поняли это правило. Jamis Buck ссылается на то, что:

/users/1/articles/1

Можно сократить до:

/articles/1

То, что вы создали, - это маршрут тщеславия, который фактически эквивалентен:

:username/articles/1

И, конечно, bob/arcticles выглядит красиво, но у него есть серьезные проблемы. Если вы позволите пользователям выбирать имена пользователей и размещать их в root «пространстве имен» ваших маршрутов, вам придется решать проблему, связанную с тем, что имена пользователей могут указывать sh на любые существующие или запланированные маршруты вашего приложения. Действительно ли оно того стоит для «симпатичных URL»?

:username/articles также менее RESTful, чем users/:username/articles, поскольку вы фактически потеряли уровень контекстной информации, описывающей ресурс. REST о значимых URL. Не короткие и красивые URL.

...