-
-
Save dhh/10022098 to your computer and use it in GitHub Desktop.
# config/routes.rb | |
resources :documents do | |
scope module: 'documents' do | |
resources :versions do | |
post :restore, on: :member | |
end | |
resource :lock | |
end | |
end | |
# app/controllers/documents_controller.rb | |
class DocumentsController < ApplicationController | |
include ProjectScoped | |
def index | |
@documents = @project.documents | |
end | |
def show | |
@document = @project.documents.find(params[:id]) | |
end | |
def new | |
@document = Document.new | |
end | |
def create | |
@document = @project.documents.create! document_params.merge(creator: current_person) | |
end | |
end | |
# app/controllers/documents/locks_controller.rb | |
module Documents | |
class LocksController < ApplicationController | |
include DocumentScoped, ProjectScoped | |
def update | |
@document.lock!(current_person) | |
end | |
def destroy | |
@document.unlock!(current_person) | |
end | |
end | |
end | |
# app/controllers/documents/versions_controller.rb | |
module Documents | |
class VersionsController < ApplicationController | |
include DocumentScoped, ProjectScoped | |
before_action :set_version | |
def show | |
end | |
def restore | |
@document.restore!(@version) | |
end | |
private | |
def set_version | |
@version = @document.versions.find(params[:id]) | |
end | |
end | |
end | |
# app/controllers/concerns/document_scoped.rb | |
module DocumentScoped | |
extend ActiveSupport::Concern | |
included do | |
before_action :set_document | |
end | |
private | |
def set_document | |
@document = @project.documents.find(params[:document_id]) | |
end | |
end |
@dhh Re: DocumentScoped / ProjectScoped order, is it a Ruby quirk or ActiveSupport::Concern
's? I thought ActiveSupport::Concern
saves dependencies in an Array and we could reverse it if that's what we want. Was there any reason that we don't do it that way?
@pixeltrix, yes of course. I've updated the gist to reflect that. Definitely nicer!
@kenn, that's a Ruby quirk. Concern is a module itself, it doesn't change how #include operates.
@dhh Wouldn't including ProjectScoped
in DocumentScoped
make the module dependency explicit, and thus allow you to remove ProjectScoped
's inclusion from Documents::VersionsController
and Documents::LocksController
, avoiding the module ordering quirk entirely?
Also, any particular reason why you call Document.new
here, instead of @project.documents.build
?
@dhh would you then apply this namespacing also for models?
So document's versions would go to document
folder as version.rb
with class Document::Version
? Same thing with locks to lock.rb
to document
folder with class Document::Lock
.
Final tree structure would be then
models/document/version.rb
models/document/lock
class Document::Version
# code here
end
or wrap those classes in plural module?
models/documents/version.rb
models/documents/lock
module Documents
class Version
# code here
end
end
@dhh you can simplify the routes by wrapping the nested resources with a scope, e.g: