controller_resources 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/rspec CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('rspec-core', 'rspec')
17
+ load Gem.bin_path("rspec-core", "rspec")
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('rubocop', 'rubocop')
17
+ load Gem.bin_path("rubocop", "rubocop")
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('parser', 'ruby-parse')
17
+ load Gem.bin_path("parser", "ruby-parse")
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('parser', 'ruby-rewrite')
17
+ load Gem.bin_path("parser", "ruby-rewrite")
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('sprockets', 'sprockets')
17
+ load Gem.bin_path("sprockets", "sprockets")
data/bin/thor CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('thor', 'thor')
17
+ load Gem.bin_path("thor", "thor")
data/bin/yard CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('yard', 'yard')
17
+ load Gem.bin_path("yard", "yard")
data/bin/yardoc CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('yard', 'yardoc')
17
+ load Gem.bin_path("yard", "yardoc")
data/bin/yri CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
  #
3
4
  # This file was generated by Bundler.
4
5
  #
@@ -6,11 +7,11 @@
6
7
  # this file is here to facilitate running it.
7
8
  #
8
9
 
9
- require 'pathname'
10
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
11
12
  Pathname.new(__FILE__).realpath)
12
13
 
13
- require 'rubygems'
14
- require 'bundler/setup'
14
+ require "rubygems"
15
+ require "bundler/setup"
15
16
 
16
- load Gem.bin_path('yard', 'yri')
17
+ load Gem.bin_path("yard", "yri")
@@ -33,12 +33,10 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency 'codeclimate-test-reporter', '~> 0'
34
34
  spec.add_development_dependency 'rubocop', '~> 0'
35
35
  spec.add_development_dependency 'capybara', '~> 2'
36
- # spec.add_development_dependency 'poltergeist', '~> 1.7'
37
36
  spec.add_development_dependency 'database_cleaner', '~> 1'
38
37
  spec.add_development_dependency 'pry', '~> 0'
39
38
  spec.add_development_dependency 'yard', '~> 0'
40
39
  spec.add_development_dependency 'travis-release', '~> 0'
41
40
 
42
- spec.add_dependency 'rails', '~> 4'
43
- spec.add_dependency 'decent_exposure', '~> 2'
41
+ spec.add_dependency 'rails'
44
42
  end
@@ -1,17 +1,127 @@
1
1
  require 'active_support/all'
2
- require 'decent_exposure'
3
2
  require 'controller_resources/version'
4
3
 
5
- # A mixin for ActionController that helps define singular and collection
6
- # model resources with permitted attributes all in one big macro.
4
+ # A mixin for +ActionController+ for easily and consistently finding
5
+ # resource objects to be used in the controller and view layer.
7
6
  module ControllerResources
8
- extend ActiveSupport::Autoload
7
+ extend ActiveSupport::Concern
9
8
 
10
- autoload :NotDefinedError
11
- autoload :Extension
12
- autoload :Engine
13
- end
9
+ included do
10
+ class_attribute :resource_name
11
+ class_attribute :resource_finder_method
12
+ class_attribute :resource_search_method
13
+ class_attribute :resource_id_param
14
+ class_attribute :resource_class_name
15
+ class_attribute :resource_ancestor_name
16
+ class_attribute :collection_actions
17
+ self.collection_actions ||= %i(index)
18
+ end
19
+
20
+ class_methods do
21
+ # Define the resource this controller will be manipulating, and call
22
+ # the +:find_resource+ callback before most actions in order to set
23
+ # up the resource automatically.
24
+ #
25
+ # @param [Symbol] name - Lowercased name of the resource.
26
+ # @option [Symbol] :ancestor - Optional ancestor ivar name.
27
+ def resource(name, ancestor: nil, finder: :find, searcher: :where, param: :id, class_name: nil)
28
+ self.resource_name = name.to_s
29
+ self.resource_ancestor_name = ancestor.to_s if ancestor.present?
30
+ self.resource_search_method = searcher
31
+ self.resource_finder_method = finder
32
+ self.resource_id_param = param
33
+ self.resource_class_name = class_name || resource_name.classify
34
+
35
+ before_action :find_resource, except: [:new, :create]
36
+ end
37
+ end
38
+
39
+ protected
40
+
41
+ # Pluralized name of the resource.
42
+ #
43
+ # @protected
44
+ # @return [String]
45
+ def plural_resource_name
46
+ resource_name.pluralize
47
+ end
48
+
49
+ # Runs before every action to determine its resource in an instance
50
+ # variable.
51
+ #
52
+ # @protected
53
+ def find_resource
54
+ if collection?
55
+ instance_variable_set "@#{plural_resource_name}", collection
56
+ else
57
+ instance_variable_set "@#{resource_name}", model
58
+ end
59
+ end
60
+
61
+ # Find the collection by its search params.
62
+ #
63
+ # @protected
64
+ # @return [Object]
65
+ def collection
66
+ model_class.send resource_search_method, search_params
67
+ end
68
+
69
+ # Find the model by its ID, or return a new model.
70
+ #
71
+ # @protected
72
+ # @return [Object]
73
+ def model
74
+ model_class.send resource_finder_method, resource_id
75
+ end
76
+
77
+ # Find the ancestor of this model if it's defined. Used in the
78
+ # +model_class+ to use as the base object by which we derive models in
79
+ # this controller.
80
+ #
81
+ # @protected
82
+ # @return [Object] or +nil+ if the ancestor was not configured.
83
+ def ancestor
84
+ return unless resource_ancestor_name.present?
85
+ instance_variable_get "@#{resource_ancestor_name}"
86
+ end
87
+
88
+ private
89
+
90
+ # Test whether current +action_name+ is in the +collection_actions+
91
+ # Array.
92
+ #
93
+ # @return [Boolean] +true+ if action needs a collection as its resource.
94
+ def collection?
95
+ collection_actions.include? action_name.to_sym
96
+ end
97
+
98
+ # Override this method to provide your own search params.
99
+ #
100
+ # @private
101
+ # @return [ActionController::Parameters] Params given to the search
102
+ # method.
103
+ def search_params
104
+ params.permit!.except(:controller, :action, :format)
105
+ end
106
+
107
+ # @private
108
+ # @return [Class] Class constant for the given resource derived from
109
+ # +resource_name+.
110
+ def model_class
111
+ ancestor_resource || resource_class_name.constantize
112
+ end
113
+
114
+ def ancestor_resource
115
+ return unless ancestor.present?
116
+ return unless ancestor.respond_to? plural_resource_name
117
+ ancestor.send plural_resource_name
118
+ end
14
119
 
15
- ActiveSupport.on_load :action_controller do
16
- include ControllerResources::Extension
120
+ # Override to provide your own finder param.
121
+ #
122
+ # @private
123
+ # @return [String] Param used to find a model, by default +params[:id]+
124
+ def resource_id
125
+ params[resource_id_param]
126
+ end
17
127
  end
@@ -1,4 +1,4 @@
1
1
  module ControllerResources
2
2
  # Current version of this gem.
3
- VERSION = '0.1.2'
3
+ VERSION = '1.0.0'
4
4
  end
@@ -1,4 +1,6 @@
1
1
  class ApplicationController < ActionController::Base
2
+ include ControllerResources
3
+
2
4
  # Prevent CSRF attacks by raising an exception.
3
5
  # For APIs, you may want to use :null_session instead.
4
6
  protect_from_forgery with: :exception
@@ -1,7 +1,5 @@
1
1
  class PostsController < ApplicationController
2
- resource :post do
3
- permit :title, :body
4
- end
2
+ resource :post
5
3
 
6
4
  # GET /posts
7
5
  def index
@@ -15,7 +13,7 @@ class PostsController < ApplicationController
15
13
 
16
14
  # GET /posts/new
17
15
  def new
18
- render :new
16
+ @post = Post.new
19
17
  end
20
18
 
21
19
  # GET /posts/1/edit
@@ -25,19 +23,28 @@ class PostsController < ApplicationController
25
23
 
26
24
  # POST /posts
27
25
  def create
28
- post.save
29
- redirect_to post
26
+ @post = Post.create edit_params
27
+ flash[:notice] = 'Post created.'
28
+ redirect_to @post
30
29
  end
31
30
 
32
31
  # PATCH/PUT /posts/1
33
32
  def update
34
- post.update(edit_params)
35
- redirect_to post
33
+ @post.update edit_params
34
+ flash[:notice] = 'Post updated.'
35
+ redirect_to @post
36
36
  end
37
37
 
38
38
  # DELETE /posts/1
39
39
  def destroy
40
- post.destroy
40
+ @post.destroy
41
+ flash[:notice] = 'Post deleted.'
41
42
  redirect_to posts_path
42
43
  end
44
+
45
+ private
46
+
47
+ def edit_params
48
+ params.require(:post).permit :title, :body
49
+ end
43
50
  end
@@ -1,4 +1,4 @@
1
- <%= form_for post do |f| %>
1
+ <%= form_for @post do |f| %>
2
2
  <div class="field">
3
3
  <%= f.label :title, 'Title' %><br>
4
4
  <%= f.text_field :title %>
@@ -2,5 +2,5 @@
2
2
 
3
3
  <%= render 'form' %>
4
4
 
5
- <%= link_to 'Show', post %> |
5
+ <%= link_to 'Show', @post %> |
6
6
  <%= link_to 'Back', posts_path %>
@@ -12,8 +12,8 @@
12
12
  </thead>
13
13
 
14
14
  <tbody>
15
- <% posts.each do |post| %>
16
- <tr>
15
+ <% @posts.each do |post| %>
16
+ <tr id="post-<%= post.id %>">
17
17
  <td><%= post.title %></td>
18
18
  <td><%= post.body %></td>
19
19
  <td><%= link_to 'Show', post %></td>