이것은 "실제 프로젝트"문제 중 하나입니다. 좋은 해결책을 찾기 위해 애쓰는 중입니다.Rails 4+ : 여러 개의 연관이있는 단일 리소스, 컨트롤러 구성
나는 여러 개의 다른 리소스와 관련된 모델을 가지고 있으며 관련 리소스 각각에서 CRUD 기능을 허용해야합니다. 예를 들어
는 project
많은 tasks
가지고 있으며, 나는 project
의 맥락에서 tasks
을 업데이트해야합니다.
또한, 각각의 project
은 많은 milestones
을 가지며, 각 milestone
은 많은 tasks
을 가질 수있다.
task
은 milestone
에 연결될 수도 있고 연결되지 않을 수도 있습니다.
class Project < ApplicationRecord
has_many :milestones
has_many :tasks
end
class Milestone < ApplicationRecord
belongs_to :project # required
has_many :tasks
end
class Task < ApplicationRecord
belongs_to :project # required
belongs_to :milestone # optional
end
더 나은 구성과 제어를 위해 내 컨트롤러 이름을 지정했습니다. 내 행동이 <action>.js.erb
형식을 따라야 그래서 내가 대신 페이지를 업데이트 자바 스크립트를 사용하는 경우,
# routes.rb
resources :projects do
namespace :projects do
resources :milestones # app/controllers/projects/milestones_controller.rb
resources :tasks # app/controllers/projects/tasks_controller.rb
end
end
resources :milestones do
namespace :milestones do
resources :tasks # app/controllers/milestones/tasks_controller.rb
end
end
나는 또한 빠른 (Turbolinks 포함) 인터페이스를 만들기 위해 AJAX를 많이 사용하고 있습니다 : 그것은 다음과 같은 경로로 날 리드 페이지 새로 고침. 내가 task
양식에 대해서도 대화 상자/팝업 인터페이스를 사용하고 있습니다. 따라서 전체 페이지 새로 고침을 할 수없는 이유는 무엇입니까?
"작동"하는 동안, 그것은 내가 많은 중복 코드가있는 상황으로 끝납니다.
# projects/tasks_controller.rb
def new
@project = Project.find(params[:project_id])
@task = @project.tasks.new
end
def create
@project = Project.find(params[:project_id])
@task = @project.tasks.new(task_params)
if @task.save
# create.js.erb
else
render js: "alert('error');" # example...
end
end
# app/views/projects/tasks/create.js.erb
$("#tasks_for_<%= dom_id(@project) %>").append("<%=j render(partial: 'projects/tasks/task') %>");
# milestones/tasks_controller.rb
def new
@milestone = Milestone.find(params[:milestone_id])
@task = @milestone.tasks.new
end
def create
@milestone = Milestone.find(params[:milestone_id])
@task = @milestone.tasks.new(task_params)
if @task.save
# create.js.erb
else
render js: "alert('error');" # example...
end
end
# app/views/milestones/tasks/create.js.erb
$("#tasks_for_<%= dom_id(@milestone) %>").append("<%=j render(partial: 'milestones/tasks/task') %>");
이것은 실제 시스템의 코드가 더 많은 중복을 보여주는 일부 샘플 코드입니다. 여러분이 알 수 있듯이 tasks
리소스와 약간 다른 상호 작용을하는 서로 다른 리소스마다 반복 코드가 많이 있습니다.
몇 가지 다른 리소스로 조작되는 리소스를 구조화하는 데 도움이되는 표준 형식이나 레일스 기능이 있습니까?
어떻게하면이 중복을 줄일 수 있습니까? 그것은 필자가 기능을 추가하거나 변경할 때마다 3 개 이상의 다른 장소로 가서 변경해야하는 복잡한 시스템으로 직접 연결됩니다.
이것이 바로 발표자, 서비스, 관리자 등 (모두 평범한 오래된 루비 개체)을 사용해야하는 이유입니다. – jvillian
@ jvillian : 발표자, 서비스 개체 및 다른 PORO를 사용합니다. 그러나 컨트롤러와 뷰의 중복을 줄이는 데 어떻게 도움이 될지 모르겠습니다. 문제는 실제로 3 개 이상의 장소가 동일한 코드의 90 %를 사용한다는 것이며, 코드를 말라 버리는 방법을 모르지만 여전히 그 10 %의 차이를 허용합니다. –