benhoskings-hammock 0.3.9 → 0.3.10

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/History.txt CHANGED
@@ -1,3 +1,21 @@
1
+ == 0.3.10 2009-07-19
2
+ Updated to newgem v1.5.1.
3
+ Sort componenets before requiring, for consistent require order.
4
+ Added preliminary prefix and singleton support to RouteStep, renaming 'resource' to 'node' (since it's a RouteNode).
5
+ Added preliminary prefix and singleton resource support to RouteNode.
6
+ Redesigned scope lookups to choose verb-specific scopes whenever possible, defaulting to :read or :write depending whether the route is safe.
7
+ Added RouteStep#default_verb.
8
+ Cleaned up RouteNode#base_for, using Array#pick.
9
+ Added RouteNode#default_verb_for.
10
+ Added RouteNode#safe_for?.
11
+ Improved error message in RouteNode#for.
12
+ Added RouteNote#all_routes hash.
13
+ Added Array#pick - like #detect, but returns the result of the block instead of the original element.
14
+ Use #camelize instead of #classify in Hammock.load_models, to avoid changing the plurality.
15
+ Added block support to Array#discard[!].
16
+ Removed unneeded self. calls from ArrayPatches.
17
+
18
+
1
19
  == 0.3.9 2009-06-18
2
20
  Improved logging in find_record_on_create.
3
21
  Enabled :indicate_current support in #hamlink_to, using RouteStep#matches?.
data/Rakefile CHANGED
@@ -1,29 +1,21 @@
1
- %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
- %w[action_controller].each { |f| require f }
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require 'action_controller'
3
6
  require File.dirname(__FILE__) + '/lib/hammock'
4
7
 
5
- # Generate all the Rake tasks
6
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
7
- $hoe = Hoe.new('hammock', Hammock::VERSION) do |p|
8
- p.developer('Ben Hoskings', 'ben@hoskings.net')
9
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
- p.rubyforge_name = p.name
11
- p.extra_deps = [
8
+ Hoe.plugin :newgem
9
+ # Hoe.plugin :website
10
+ # Hoe.plugin :cucumberfeatures
11
+
12
+ $hoe = Hoe.spec 'hammock' do
13
+ self.developer 'Ben Hoskings', 'ben@hoskings.net'
14
+ self.extra_deps = [
12
15
  ['rails', '~> 2.2'],
13
16
  ['benhoskings-ambitious-activerecord', '~> 0.1.3.7'],
14
17
  ]
15
- p.extra_dev_deps = [
16
- ['newgem', ">= #{::Newgem::VERSION}"]
17
- ]
18
-
19
- p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
- p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
- p.rsync_args = '-av --delete --ignore-errors'
23
18
  end
24
19
 
25
- require 'newgem/tasks' # load /tasks/*.rake
20
+ require 'newgem/tasks'
26
21
  Dir['tasks/**/*.rake'].each { |t| load t }
27
-
28
- # TODO - want other tests/tasks run by default? Add them to the list
29
- # task :default => [:spec, :features]
data/hammock.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{hammock}
5
- s.version = "0.3.9"
5
+ s.version = "0.3.10"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Ben Hoskings"]
9
- s.date = %q{2009-06-18}
9
+ s.date = %q{2009-07-19}
10
10
  s.description = %q{Hammock is a Rails plugin that eliminates redundant code in a very RESTful manner. It does this in lots in lots of different places, but in one manner: it encourages specification in place of implementation.
11
11
 
12
12
 
@@ -18,7 +18,7 @@ Hammock inspects your routes and resources to generate a routing tree for each r
18
18
 
19
19
  It makes more sense when you see how it works though. There's a screencast coming soon.}
20
20
  s.email = ["ben@hoskings.net"]
21
- s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc", "misc/scaffold.txt"]
21
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "misc/scaffold.txt"]
22
22
  s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "hammock.gemspec", "init.rb", "lib/hammock.rb", "lib/hammock/ajaxinate.rb", "lib/hammock/callback.rb", "lib/hammock/callbacks.rb", "lib/hammock/canned_scopes.rb", "lib/hammock/constants.rb", "lib/hammock/controller_attributes.rb", "lib/hammock/export_scope.rb", "lib/hammock/hamlink_to.rb", "lib/hammock/javascript_buffer.rb", "lib/hammock/lambda_alias.rb", "lib/hammock/lambda_composition.rb", "lib/hammock/logging.rb", "lib/hammock/model_attributes.rb", "lib/hammock/model_logging.rb", "lib/hammock/monkey_patches/action_pack.rb", "lib/hammock/monkey_patches/active_record.rb", "lib/hammock/monkey_patches/array.rb", "lib/hammock/monkey_patches/hash.rb", "lib/hammock/monkey_patches/logger.rb", "lib/hammock/monkey_patches/module.rb", "lib/hammock/monkey_patches/numeric.rb", "lib/hammock/monkey_patches/object.rb", "lib/hammock/monkey_patches/route_set.rb", "lib/hammock/monkey_patches/string.rb", "lib/hammock/mutex.rb", "lib/hammock/overrides.rb", "lib/hammock/resource_mapping_hooks.rb", "lib/hammock/resource_retrieval.rb", "lib/hammock/restful_actions.rb", "lib/hammock/restful_rendering.rb", "lib/hammock/restful_support.rb", "lib/hammock/route_drawing_hooks.rb", "lib/hammock/route_for.rb", "lib/hammock/route_node.rb", "lib/hammock/route_step.rb", "lib/hammock/scope.rb", "lib/hammock/suggest.rb", "lib/hammock/utils.rb", "misc/scaffold.txt", "misc/template.rb", "tasks/hammock_tasks.rake", "test/hammock_test.rb"]
23
23
  s.homepage = %q{http://github.com/benhoskings/hammock}
24
24
  s.rdoc_options = ["--main", "README.rdoc"]
@@ -34,18 +34,15 @@ It makes more sense when you see how it works though. There's a screencast comin
34
34
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
35
35
  s.add_runtime_dependency(%q<rails>, ["~> 2.2"])
36
36
  s.add_runtime_dependency(%q<benhoskings-ambitious-activerecord>, ["~> 0.1.3.7"])
37
- s.add_development_dependency(%q<newgem>, [">= 1.4.1"])
38
- s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
37
+ s.add_development_dependency(%q<hoe>, [">= 2.3.2"])
39
38
  else
40
39
  s.add_dependency(%q<rails>, ["~> 2.2"])
41
40
  s.add_dependency(%q<benhoskings-ambitious-activerecord>, ["~> 0.1.3.7"])
42
- s.add_dependency(%q<newgem>, [">= 1.4.1"])
43
- s.add_dependency(%q<hoe>, [">= 1.8.0"])
41
+ s.add_dependency(%q<hoe>, [">= 2.3.2"])
44
42
  end
45
43
  else
46
44
  s.add_dependency(%q<rails>, ["~> 2.2"])
47
45
  s.add_dependency(%q<benhoskings-ambitious-activerecord>, ["~> 0.1.3.7"])
48
- s.add_dependency(%q<newgem>, [">= 1.4.1"])
49
- s.add_dependency(%q<hoe>, [">= 1.8.0"])
46
+ s.add_dependency(%q<hoe>, [">= 2.3.2"])
50
47
  end
51
48
  end
@@ -9,12 +9,12 @@ module Hammock
9
9
 
10
10
  module ClassMethods
11
11
 
12
- def has_public_scope? scope_name
13
- "#{scope_name}able" if respond_to? "#{scope_name}_scope"
12
+ def public_scope_for verb
13
+ "#{verb}able" if respond_to? "#{verb}_scope"
14
14
  end
15
15
 
16
- def has_account_scope? scope_name
17
- "#{scope_name}able_by" if respond_to? "#{scope_name}_scope_for"
16
+ def user_scope_for verb
17
+ "#{verb}able_by" if respond_to? "#{verb}_scope_for"
18
18
  end
19
19
 
20
20
  def export_scopes *verbs
@@ -22,18 +22,25 @@ module Hammock
22
22
  self[-other.length, other.length] == other
23
23
  end
24
24
 
25
+ def pick &block
26
+ value = nil
27
+ detect {|i| value = yield(i) }
28
+ value
29
+ end
30
+
25
31
  def squash
26
- self.dup.squash!
32
+ dup.squash!
27
33
  end
28
34
  def squash!
29
- self.delete_if &:blank?
35
+ delete_if &:blank?
30
36
  end
31
37
 
32
- def discard *args
33
- self.dup.discard! *args
38
+ def discard *args, &block
39
+ dup.discard! *args, &block
34
40
  end
35
- def discard! *args
36
- args.each {|arg| self.delete arg }
41
+ def discard! *args, &block
42
+ args.each {|arg| delete arg }
43
+ each {|i| delete(i) if yield(i) } if block_given?
37
44
  self
38
45
  end
39
46
 
@@ -55,7 +62,7 @@ module Hammock
55
62
  this_method = methods.shift
56
63
 
57
64
  # First, hash this array into +hsh+.
58
- self.each {|i| hsh[i.send(this_method)] << i }
65
+ each {|i| hsh[i.send(this_method)] << i }
59
66
 
60
67
  if methods.empty?
61
68
  # If there are no methods remaining, yield this group to the block if required.
@@ -69,14 +69,14 @@ module Hammock
69
69
  elsif :readonly == reason
70
70
  escort_for_read_only
71
71
  elsif :unauthed == reason
72
- if current_user.nil? && request.get? && account_verb_scope?
72
+ if current_user.nil? && request.get? && current_user_scope
73
73
  # This request may be available after a login, and can be replayed
74
74
  redirect_to returning_login_path
75
75
  else
76
76
  # TODO Write a 403 partial.
77
77
  render_for_status 404
78
78
  end
79
- elsif current_user.nil? && account_verb_scope?
79
+ elsif current_user.nil? && current_user_scope
80
80
  escort_for_login
81
81
  else
82
82
  render_for_status 404
@@ -145,10 +145,6 @@ module Hammock
145
145
  end
146
146
  end
147
147
 
148
- def safe_verb_and_implication?
149
- request.get? && !action_name.to_sym.in?(Hammock::Constants::ImpliedUnsafeActions)
150
- end
151
-
152
148
  def set_editing
153
149
  @editing = @record
154
150
  end
@@ -15,11 +15,13 @@ module Hammock
15
15
  :create => :post
16
16
  }.freeze
17
17
 
18
- attr_reader :mdl, :resource, :parent, :children, :routing_parent, :record_routes, :resource_routes, :build_routes
18
+ attr_reader :mdl, :resource, :parent, :children, :prefix, :routing_parent, :record_routes, :resource_routes, :build_routes, :all_routes
19
19
 
20
20
  def initialize entity = nil, options = {}
21
21
  @parent = options[:parent]
22
22
  @children = {}
23
+ @options = options[:name_prefix]
24
+ @singleton = options[:singleton]
23
25
  unless root?
24
26
  @mdl = entity if entity.is_a?(Symbol)
25
27
  @routing_parent = determine_routing_parent
@@ -32,16 +34,28 @@ module Hammock
32
34
  Object.const_get mdl.to_s.classify rescue nil
33
35
  end
34
36
 
37
+ def default_verb_for verb
38
+ safe_for?(verb) ? :read : :write
39
+ end
40
+
35
41
  def root?
36
42
  parent.nil?
37
43
  end
38
44
 
45
+ def safe_for? verb
46
+ (:get == all_routes[verb]) && !verb.in?(Hammock::Constants::ImpliedUnsafeActions)
47
+ end
48
+
49
+ def singleton?
50
+ @singleton
51
+ end
52
+
39
53
  def ancestry
40
54
  root? ? [] : parent.ancestry.push(self)
41
55
  end
42
56
 
43
57
  def for verb, entities, options
44
- raise "Hammock::RouteNode#for requires an explicitly specified verb as its first argument." unless verb.is_a?(Symbol)
58
+ raise "Hammock::RouteNode#for requires a verb (as a symbol) as its first argument." unless verb.is_a?(Symbol)
45
59
  raise "Hammock::RouteNode#for requires an Array of at least one record or resource." if entities.empty? || !entities.is_a?(Array)
46
60
 
47
61
  entity = entities.shift
@@ -54,22 +68,16 @@ module Hammock
54
68
  end
55
69
 
56
70
  def base_for resources
57
- # puts "base_for<#{mdl}>: resources=#{resources.inspect}."
58
71
  if resources.empty?
59
- self
72
+ if root?
73
+ raise "You have to supply at least one valid resource to find its routing base."
74
+ else
75
+ self
76
+ end
60
77
  else
61
- match = nil
62
- children.values.detect {|child|
63
- # puts " Trying #{child.ancestry.map(&:mdl).inspect} for #{resources.inspect}"
64
- if !resources.include?(child.mdl)
65
- # puts " Can't match #{resources.inspect} against #{child.mdl}."
66
- nil
67
- else
68
- # puts " Matched #{child.mdl} from #{resources.inspect}."
69
- match = child.base_for resources.discard(child.mdl)
70
- end
71
- } #|| raise("There is no routing path for #{resources.map(&:inspect).inspect}.")
72
- match
78
+ children.values.pick {|child|
79
+ child.base_for resources.discard(child.mdl) if resources.include?(child.mdl)
80
+ }
73
81
  end
74
82
  end
75
83
 
@@ -89,13 +97,19 @@ module Hammock
89
97
  eval "resource.select {|r| r.#{resource.routing_attribute} == value }"
90
98
  end
91
99
 
92
- def add entity, options, steps = nil
93
- if steps.nil?
94
- add entity, options, (options[:name_prefix] || '').chomp('_').split('_').map {|i| i.pluralize.underscore.to_sym }
95
- elsif steps.empty?
100
+ def add_singleton entity, options, path_steps = nil
101
+ add entity, options.merge(:singleton => true), path_steps
102
+ end
103
+
104
+ def add entity, options, path_steps = nil
105
+ # puts "add(#{entity.inspect}, #{options.inspect}, #{path_steps.inspect})"
106
+ if path_steps.nil?
107
+ path_steps = (options[:path_prefix] || '').split('/').squash.discard {|i| i.starts_with? ':' }.map(&:to_sym)
108
+ add entity, options, path_steps
109
+ elsif path_steps.empty?
96
110
  add_child entity, options
97
111
  else
98
- children[steps.shift].add entity, options, steps
112
+ children[path_steps.shift].add entity, options, path_steps
99
113
  end
100
114
  end
101
115
 
@@ -115,6 +129,7 @@ module Hammock
115
129
  @record_routes = DefaultRecordVerbs.dup.update(options[:member] || {})
116
130
  @resource_routes = DefaultResourceVerbs.dup.update(options[:collection] || {})
117
131
  @build_routes = DefaultBuildVerbs.dup.update(options[:build] || {})
132
+ @all_routes = @record_routes.merge(@resource_routes).merge(@build_routes)
118
133
  end
119
134
 
120
135
  def determine_routing_parent
@@ -1,13 +1,13 @@
1
1
  module Hammock
2
2
  class RouteStep
3
- attr_reader :resource, :routeable_as, :verb, :entity, :parent
3
+ attr_reader :node, :routeable_as, :verb, :entity, :parent
4
4
 
5
- def initialize resource
6
- @resource = resource
5
+ def initialize node
6
+ @node = node
7
7
  end
8
8
 
9
9
  def for verb, entity
10
- routeable_as = resource.routeable_as(verb, entity)
10
+ routeable_as = node.routeable_as(verb, entity)
11
11
 
12
12
  if !routeable_as
13
13
  raise "The verb '#{verb}' can't be applied to " + (entity.record? ? "#{entity.resource} records" : "the #{entity.resource} resource") + "."
@@ -40,8 +40,15 @@ module Hammock
40
40
  raise_unless_setup_while_trying_to 'render a path'
41
41
 
42
42
  buf = '/'
43
- buf << entity.resource_name
44
- buf << '/' + entity.to_param if entity.record? && !entity.new_record?
43
+ buf << node.prefix unless node.prefix.nil?
44
+
45
+ if node.singleton?
46
+ buf << entity.resource_name.singularize
47
+ else
48
+ buf << entity.resource_name
49
+ buf << '/' + entity.to_param if entity.record? && !entity.new_record?
50
+ end
51
+
45
52
  buf << '/' + verb.to_s unless verb.nil? or implied_verb?(verb)
46
53
 
47
54
  buf = parent.path + buf unless parent.nil?
@@ -52,7 +59,7 @@ module Hammock
52
59
 
53
60
  def http_method
54
61
  raise_unless_setup_while_trying_to 'extract the HTTP method'
55
- resource.send("#{routeable_as}_routes")[verb]
62
+ node.send("#{routeable_as}_routes")[verb]
56
63
  end
57
64
 
58
65
  def fake_http_method
@@ -68,6 +75,10 @@ module Hammock
68
75
  get? && !verb.in?(Hammock::Constants::ImpliedUnsafeActions)
69
76
  end
70
77
 
78
+ def default_verb
79
+ safe? ? :read : :write
80
+ end
81
+
71
82
  private
72
83
 
73
84
  def implied_verb? verb
data/lib/hammock/scope.rb CHANGED
@@ -42,35 +42,25 @@ module Hammock
42
42
  raise "The verb at #{call_point} must be supplied as a Symbol." unless verb.nil? || verb.is_a?(Symbol)
43
43
  route = route_for verb, record
44
44
  if route.verb.in?(:save, :create) && record.new_record?
45
- if !record.createable_by?(current_user)
46
- dlog "#{requester_name} can't create a #{record.class} with #{record.attributes.inspect}. #{describe_call_point 4}"
47
- :unauthed
48
- else
49
- :ok
45
+ returning record.createable_by?(current_user) ? :ok : :unauthed do |result|
46
+ dlog "#{requester_name} can#{"'t" unless result == :ok} create a #{record.class} with #{record.attributes.inspect}. #{describe_call_point 4}"
50
47
  end
51
48
  else
52
- if !record.readable_by?(current_user)
53
- dlog "#{requester_name} can't see #{record.class}<#{record.id}>. #{describe_call_point 4}"
54
- :not_found
55
- elsif !route.safe? && !record.writeable_by?(current_user)
56
- dlog "#{requester_name} can't #{verb} #{record.class}<#{record.id}>. #{describe_call_point 4}"
57
- :read_only
58
- else
59
- # dlog "#{requester_name} can #{verb} #{record.class}<#{record.id}>."
60
- :ok
49
+ returning record.send("#{scope_for_route(route)}?", current_user) ? :ok : :not_found do |result|
50
+ dlog "#{requester_name} can#{"'t" unless result == :ok} #{verb} #{record.class}<#{record.id}>. #{describe_call_point 4}"
61
51
  end
62
52
  end
63
53
  end
64
54
 
65
55
  def current_verb_scope
66
- if current_user && (scope_name = account_verb_scope?)
67
- # dlog "got an account_verb_scope #{scope_name}."
56
+ if current_user && (scope_name = current_user_scope)
57
+ # dlog "current_user_scope is #{scope_name}."
68
58
  mdl.send scope_name, current_user
69
- elsif !(scope_name = public_verb_scope?)
70
- log "No #{current_user.nil? ? 'public' : 'account'} #{scope_name_for_action} scope available for #{mdl}.#{' May be available after login.' if account_verb_scope?}"
59
+ elsif !(scope_name = current_public_scope)
60
+ log "No #{current_user.nil? ? 'public' : 'account'} #{action_name} scope available for #{mdl}.#{' May be available after login.' if current_user_scope}"
71
61
  nil
72
62
  else
73
- # dlog "got a #{scope_name} public_verb_scope."
63
+ # dlog "current_public_scope is #{scope_name}."
74
64
  mdl.send scope_name
75
65
  end
76
66
  end
@@ -101,25 +91,20 @@ module Hammock
101
91
 
102
92
  private
103
93
 
104
- def scope_name_for_action
105
- if 'index' == action_name
106
- 'index'
107
- elsif safe_verb_and_implication?
108
- 'read'
109
- else
110
- 'write'
111
- end
112
- end
113
-
114
94
  def requester_name
115
95
  current_user.nil? ? 'Anonymous' : "#{current_user.class}<#{current_user.id}>"
116
96
  end
117
97
 
118
- def account_verb_scope?
119
- mdl.has_account_scope?(action_name) || mdl.has_account_scope?(scope_name_for_action)
98
+ def current_user_scope
99
+ mdl.user_scope_for(action_name) || mdl.user_scope_for(current_hammock_resource.default_verb_for(action_name))
100
+ end
101
+ def current_public_scope
102
+ mdl.public_scope_for(action_name) || mdl.public_scope_for(current_hammock_resource.default_verb_for(action_name))
120
103
  end
121
- def public_verb_scope?
122
- mdl.has_public_scope?(action_name) || mdl.has_public_scope?(scope_name_for_action)
104
+
105
+ def scope_for_route route
106
+ method_name = current_user.nil? ? :public_scope_for : :user_scope_for
107
+ mdl.send(method_name, route.verb) || mdl.send(method_name, route.default_verb)
123
108
  end
124
109
 
125
110
  end
data/lib/hammock.rb CHANGED
@@ -4,7 +4,7 @@ require 'ambition'
4
4
  require 'ambition/adapters/active_record'
5
5
 
6
6
  module Hammock
7
- VERSION = '0.3.9'
7
+ VERSION = '0.3.10'
8
8
  IncludeTarget = ActionController::Base
9
9
 
10
10
  def self.included base # :nodoc:
@@ -21,7 +21,7 @@ module Hammock
21
21
  # and related methods always return the full set of models they should.
22
22
  def self.load_models
23
23
  Dir.glob(RAILS_ROOT / 'app/models/**/*.rb').each {|model_file|
24
- klass = File.basename(model_file, '.rb').classify
24
+ klass = File.basename(model_file, '.rb').camelize
25
25
  begin
26
26
  Object.const_get klass
27
27
  rescue
@@ -39,7 +39,7 @@ module Hammock
39
39
  end
40
40
 
41
41
  def self.require_hammock_components
42
- Dir.glob("#{File.dirname __FILE__}/hammock/**/*.rb").each {|dep|
42
+ Dir.glob("#{File.dirname __FILE__}/hammock/**/*.rb").sort.each {|dep|
43
43
  require dep
44
44
  }
45
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benhoskings-hammock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Hoskings
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-18 00:00:00 -07:00
12
+ date: 2009-07-19 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,16 +32,6 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.1.3.7
34
34
  version:
35
- - !ruby/object:Gem::Dependency
36
- name: newgem
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: 1.4.1
44
- version:
45
35
  - !ruby/object:Gem::Dependency
46
36
  name: hoe
47
37
  type: :development
@@ -50,7 +40,7 @@ dependencies:
50
40
  requirements:
51
41
  - - ">="
52
42
  - !ruby/object:Gem::Version
53
- version: 1.8.0
43
+ version: 2.3.2
54
44
  version:
55
45
  description: "Hammock is a Rails plugin that eliminates redundant code in a very RESTful manner. It does this in lots in lots of different places, but in one manner: it encourages specification in place of implementation. Hammock enforces RESTful resource access by abstracting actions away from the controller in favour of a clean, model-like callback system. Hammock tackles the hard and soft sides of security at once with a scoping security system on your models. Specify who can verb what resources under what conditions once, and everything else - the actual security, link generation, index filtering - just happens. Hammock inspects your routes and resources to generate a routing tree for each resource. Parent resources in a nested route are handled transparently at every point - record retrieval, creation, and linking. It makes more sense when you see how it works though. There's a screencast coming soon."
56
46
  email:
@@ -62,7 +52,6 @@ extensions: []
62
52
  extra_rdoc_files:
63
53
  - History.txt
64
54
  - Manifest.txt
65
- - README.rdoc
66
55
  - misc/scaffold.txt
67
56
  files:
68
57
  - History.txt