Module: Rooftop::Rails::NestedResource::ClassMethods

Defined in:
app/controllers/concerns/rooftop/rails/nested_resource.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#resource_classObject (readonly)

Returns the value of attribute resource_class.



11
12
13
# File 'app/controllers/concerns/rooftop/rails/nested_resource.rb', line 11

def resource_class
  @resource_class
end

#resource_nameObject (readonly)

Returns the value of attribute resource_name.



11
12
13
# File 'app/controllers/concerns/rooftop/rails/nested_resource.rb', line 11

def resource_name
  @resource_name
end

Instance Method Details

#nested_rooftop_resource(resource) ⇒ Object

A class method defined on the controller which gives you an easy way to find a resource from a deeply-nested path, and optionally check that the path provided is correct. By adding a call to ‘nested_rooftop_resource` in your controller class, the following happens:

  • The resource model you identify has Rooftop::Rails::NestedModel mixed into it

  • Methods for finding a model object and validating that the path is correct are added

Note that the methods on the controller are dynamically named according to the resource name - i.e. find_and_validate_page in this case. You need to set up your routes so that a single param called ‘nested_path` is passed to this controller for any methods you’re calling ‘find_and_validate_page` on, for example: match “/*nested_path”, via: [:get], to: “pages#show” This is a greedy route so you probably want it at the bottom.

Examples:

class PagesController
  include Rooftop::Rails::NestedResource
  nested_rooftop_resource :page
  before_action :find_and_validate_page, except: :index
end


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'app/controllers/concerns/rooftop/rails/nested_resource.rb', line 27

def nested_rooftop_resource(resource)
  @resource_name = resource
  @resource_class = resource.to_s.classify.constantize
  @resource_class.send(:include, Rooftop::Rails::NestedModel)

  # Set up the dynamically-named find_[resource name]
  define_method "find_#{@resource_name}" do
    respond_to do |format|
      format.html do
        resource = self.class.resource_class.send(:find_by_nested_path, params[:nested_path])
        instance_variable_set("@#{self.class.resource_name}",resource)
      end
      format.all do
        raise ActionController::RoutingError, "Not found: #{request.original_fullpath}"
      end
    end

  end
  # Set up the dynamically-named validate_[resource name]
  define_method "validate_#{@resource_name}" do
    resource = instance_variable_get("@#{self.class.resource_name}")
    if resource.nested_path != params[:nested_path]
      raise Rooftop::Rails::AncestorMismatch, "The #{self.class.resource_name} you requested has a different path"
    end
  end
  # Set up the dynamically-named find_and_validate_[resource name]
  # (this is a utility method to call the two above)
  define_method "find_and_validate_#{@resource_name}" do
    send(:"find_#{self.class.resource_name}")
    send(:"validate_#{self.class.resource_name}")
  end
end