friendly_routes 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20f66faa1c0ee03ba5ee4d409c3533c233fce5a6
4
- data.tar.gz: 86d56ad4c80db6eaefc1b72ebaabc543ac61f74e
3
+ metadata.gz: e2d3509ebae256e805600bb631718d9489eeaf73
4
+ data.tar.gz: dd5d986628e21c2d693f579e1ab621bb3a259161
5
5
  SHA512:
6
- metadata.gz: 587782afc11016d44dd17f9ed2b54e19e1f0c84ec99053ef6314473f1464460a5cfdba97f2c5839581f9815e4a0e26fcbe044e4e3e9ce010988289fba9497918
7
- data.tar.gz: 45e249b6bd390058e8d3be82fe1b716c428ed064709554af10055b99a18819ee930841ee3d2d349e95d09a6c11f6b65635019b4d615f15e450bf93b03b554eb4
6
+ metadata.gz: e9aed8430ef5abc1f2e6fffcd3956022c0ab30904d7690a9c027c6c2c5f4edec643c97ed58a8ec60da8fc098b67406ab0d0c71295e8590f93808d80e44c1de2f
7
+ data.tar.gz: 14e92badb00980a1bb3efb5a134e713146920dc8c3c6aa71baa7c28623c65f9fa05c1c54f4d2cf12e5ed1d98babeb4dc364408d2c9149ac19116e106895a9d32
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Friendly Routes
2
2
  Friendly Routes creates DSL for creating rails routes with human friendly URLs
3
3
 
4
+ [![Gem Version](https://badge.fury.io/rb/friendly_routes.svg)](https://badge.fury.io/rb/friendly_routes)
4
5
  [![Code Climate](https://codeclimate.com/github/RoM4iK/friendly_routes/badges/gpa.svg)](https://codeclimate.com/github/RoM4iK/friendly_routes)
5
6
  [![Build Status](https://travis-ci.org/RoM4iK/friendly_routes.svg?branch=master)](https://travis-ci.org/RoM4iK/friendly_routes)
6
7
  ## Usage
@@ -22,7 +23,8 @@ Or install it yourself as:
22
23
  ```bash
23
24
  $ gem install friendly_routes
24
25
  ```
25
- ## Usage example
26
+ ## Examples
27
+ ### Routes.rb example
26
28
 
27
29
  ```ruby
28
30
  # config/routes.rb
@@ -37,57 +39,31 @@ second_dummies_route = FriendlyRoutes::Route.new([free, 'categories', category],
37
39
 
38
40
  friendly_url_for dummies_route, :get, '/' # '/:free/categories/:category'
39
41
  friendly_url_for dummies_route, :get, '/hello/' # '/hello/:free/categories/:category'
42
+ ```
43
+
44
+ ### Controller example
40
45
 
46
+ ```ruby
41
47
  # app/controllers/dummies_controller.rb
42
48
  class DummiesController < ApplicationController
43
49
  before_action :parse_friendly_routes, only: [:index]
44
50
  def index
45
51
  end
46
52
  end
47
-
48
- # Categories:
49
- # <Category id: 1, title: "lorem">
50
- # <Category id: 2, title: "ipsum">
51
-
52
-
53
- # GET "/free/lorem" - { free: true, category_id: 1}
54
- # GET "/free/ipsum" - { free: true, category_id: 2}
55
- # GET "/paid/lorem" - { free: false, category_id: 1}
56
- # GET "/paid/ipsum" - { free: false, category_id: 2}
57
- ```
58
-
59
- ## Configuration
60
- ### Routes
61
-
62
- 1. Create new route, pass **method**, **path**, **controller name**, and **action** to it.
63
- ```ruby
64
- dummies_route = FriendlyRoutes::Route.new('/', controller: :dummies, action: :index)
65
53
  ```
66
- 2. Create route params. *Note: params in route will be accepted in creation order*
67
54
 
68
- Boolean param, pass **name**, and hash with **true** and **false** keys.
69
- ```ruby
70
- FriendlyRoutes::Params::BooleanParams.new(:discount, true: :true_condition, false: :false_condition)
71
- ```
55
+ ### Request result example
72
56
 
73
- collection param, pass **name**, **collection**, and **attribute** keys.
74
- ```ruby
75
- FriendlyRoutes::Params::CollectionParams.new(:categories, Category.where(active: true), :title)
76
57
  ```
58
+ Categories:
59
+ <Category id: 1, title: "lorem">
60
+ <Category id: 2, title: "ipsum">
77
61
 
78
- hash param, pass **name**, **collection**, and **attribute** keys.
79
- ```ruby
80
- FriendlyRoutes::Params::HashParams.new(:rooms, 'one-roomed' => 1, 'two-roomed' => 2)
81
- ```
82
- 4. Initialize route wih `friendly_url_for`
83
- ```ruby
84
- friendly_url_for dummies_route, :get
85
- ```
86
62
 
87
- ### Controllers
88
- Simply call `parse_friendly_routes` before controller action to parse params.
89
- ```ruby
90
- before_action :parse_friendly_routes, only: [:index]
63
+ GET "/free/lorem" - { free: true, category_id: 1}
64
+ GET "/free/ipsum" - { free: true, category_id: 2}
65
+ GET "/paid/lorem" - { free: false, category_id: 1}
66
+ GET "/paid/ipsum" - { free: false, category_id: 2}
91
67
  ```
92
68
 
93
69
  ## Contributing
@@ -7,7 +7,9 @@ require 'friendly_routes/params/base'
7
7
  require 'friendly_routes/params/boolean_params'
8
8
  require 'friendly_routes/params/collection_params'
9
9
  require 'friendly_routes/params/hash_params'
10
+ require 'friendly_routes/services/composer'
10
11
  require 'friendly_routes/services/constraints'
12
+ require 'friendly_routes/services/multi_composer'
11
13
  require 'friendly_routes/services/parser'
12
14
  require 'friendly_routes/services/prefixed_param'
13
15
  require 'friendly_routes/services/prefixed_params'
@@ -2,6 +2,11 @@
2
2
 
3
3
  module FriendlyRoutes
4
4
  module Params
5
+ # Abstract base class for route params.
6
+ #
7
+ # @abstract
8
+ # @attr [Symbol] type
9
+ # @attr [Symbol, String] name
5
10
  class Base
6
11
  attr_accessor :type, :name
7
12
 
@@ -11,13 +16,39 @@ module FriendlyRoutes
11
16
  @optional = optional
12
17
  end
13
18
 
19
+ # returns true if param is optional
14
20
  def optional?
15
21
  @optional == true
16
22
  end
17
23
 
24
+ # returns true if param required
25
+ def required?
26
+ @optional == false
27
+ end
28
+
29
+ # Regexp with allowed params
18
30
  def constraints
19
31
  raise NotImplementedError
20
32
  end
33
+
34
+ # Parse values from request
35
+ #
36
+ # Inverse of {compose}
37
+ def parse
38
+ raise NotImplementedError
39
+ end
40
+
41
+ # Generate request value from params
42
+ #
43
+ # Inverse of {parse}
44
+ def compose
45
+ raise NotImplementedError
46
+ end
47
+
48
+ # Check if value can be composed
49
+ def allowed?
50
+ raise NotImplementedError
51
+ end
21
52
  end
22
53
  end
23
54
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module FriendlyRoutes
4
4
  module Params
5
+ # @attr [String] true value for matching true
6
+ # @attr [String] false value for matching false
5
7
  class BooleanParams < Base
6
8
  attr_accessor :true, :false
7
9
 
@@ -16,10 +18,27 @@ module FriendlyRoutes
16
18
  Regexp.new "#{@true}|#{@false}"
17
19
  end
18
20
 
21
+ # (see Base#parse)
22
+ # @param [String] value request value
23
+ # @return [Boolean]
19
24
  def parse(value)
20
25
  value == @true
21
26
  end
22
27
 
28
+ # (see Base#compose)
29
+ # @param [Boolean] value
30
+ # @return [String] request value
31
+ def compose(value)
32
+ value ? @true : @false
33
+ end
34
+
35
+ # (see Base#allowed?)
36
+ # @param [Boolean] value
37
+ # @return [Boolean]
38
+ def allowed?(value)
39
+ [true, false].include? value
40
+ end
41
+
23
42
  private
24
43
 
25
44
  def check_params(options)
@@ -2,6 +2,10 @@
2
2
 
3
3
  module FriendlyRoutes
4
4
  module Params
5
+ # Created to work with ActiveRecord collection
6
+ #
7
+ # @attr [Object] collection Instance of ActiveRecord collection
8
+ # @attr [Symbol, String] key_attr name of attribute for matching
5
9
  class CollectionParams < Base
6
10
  attr_accessor :collection, :key_attr
7
11
 
@@ -16,10 +20,27 @@ module FriendlyRoutes
16
20
  Regexp.new @collection.all.map(&@key_attr).compact.map(&:downcase).join('|')
17
21
  end
18
22
 
23
+ # (see Base#parse)
24
+ # @param [String] value value of item key attr
25
+ # @return [Integer, nil] item id or nil if item not found
19
26
  def parse(value)
20
27
  @collection.find_by(@key_attr => value).try(:id)
21
28
  end
22
29
 
30
+ # (see Base#compose)
31
+ # @param [Integer] id id of collection member
32
+ # @return [String] member key attr
33
+ def compose(id)
34
+ @collection.find(id)[@key_attr]
35
+ end
36
+
37
+ # (see Base#allowed?)
38
+ # @param [Integer] id id of collection member
39
+ # @return [Boolean]
40
+ def allowed?(id)
41
+ @collection.exists?(id)
42
+ end
43
+
23
44
  private
24
45
 
25
46
  def check_params
@@ -2,6 +2,7 @@
2
2
 
3
3
  module FriendlyRoutes
4
4
  module Params
5
+ # @attr [Hash] hash *keys* are values for matching and *values* is needed values
5
6
  class HashParams < Base
6
7
  attr_accessor :hash
7
8
 
@@ -15,10 +16,27 @@ module FriendlyRoutes
15
16
  Regexp.new @hash.keys.join('|')
16
17
  end
17
18
 
19
+ # (see Base#parse)
20
+ # @param [String, Symbol] value hash key
21
+ # @return [Object] hash value
18
22
  def parse(value)
19
23
  @hash[value]
20
24
  end
21
25
 
26
+ # (see Base#compose)
27
+ # @param [Object] value hash value
28
+ # @return [String, Symbol] hash key
29
+ def compose(value)
30
+ @hash.key(value)
31
+ end
32
+
33
+ # (see Base#allowed?)
34
+ # @param [Integer] value hash value
35
+ # @return [Boolean]
36
+ def allowed?(value)
37
+ @hash.values.include?(value)
38
+ end
39
+
22
40
  private
23
41
 
24
42
  def check_params
@@ -21,6 +21,10 @@ module FriendlyRoutes
21
21
  @params.select { |param| param.is_a?(FriendlyRoutes::Params::Base) }
22
22
  end
23
23
 
24
+ def required_params
25
+ dynamic_params.select(&:required?)
26
+ end
27
+
24
28
  def inspect
25
29
  dynamic_params.map(&:name).join(', ')
26
30
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FriendlyRoutes
4
+ # Compoer will map passed params to friendly_route params
5
+ class Composer
6
+ def initialize(route, params = {})
7
+ @route = route
8
+ @params = params.dup
9
+ end
10
+
11
+ def call
12
+ return unless @route
13
+ @route.dynamic_params.each do |param|
14
+ compose(param)
15
+ end
16
+ @params
17
+ end
18
+
19
+ def can_be_composed?
20
+ return unless @route
21
+ @route.required_params.all? do |param|
22
+ param.allowed? @params[param.name]
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def compose(param)
29
+ value = @params[param.name]
30
+ return unless param.allowed?(value)
31
+ prefixed_name = FriendlyRoutes::PrefixedParam.new(param.name, @route.prefix).call
32
+ @params[prefixed_name] = param.compose(value)
33
+ @params.delete(param.name) unless param.name == prefixed_name
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FriendlyRoutes
4
+ # Compoer will map passed params to friendly_route params
5
+ class MultiComposer
6
+ attr_reader :matched_route
7
+
8
+ def initialize(routes, params = {})
9
+ @routes = routes
10
+ @params = params.dup
11
+ end
12
+
13
+ def call
14
+ compose unless @composed_params
15
+ @composed_params
16
+ end
17
+
18
+ private
19
+
20
+ def compose
21
+ @routes.each do |route|
22
+ composer = Composer.new(route, @params)
23
+ next unless composer.can_be_composed?
24
+ @matched_route = route
25
+ @composed_params = composer.call
26
+ break
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FriendlyRoutes
4
- VERSION = '0.3.3'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friendly_routes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Gritsay
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-07 00:00:00.000000000 Z
11
+ date: 2016-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -147,7 +147,9 @@ files:
147
147
  - lib/friendly_routes/params/collection_params.rb
148
148
  - lib/friendly_routes/params/hash_params.rb
149
149
  - lib/friendly_routes/route.rb
150
+ - lib/friendly_routes/services/composer.rb
150
151
  - lib/friendly_routes/services/constraints.rb
152
+ - lib/friendly_routes/services/multi_composer.rb
151
153
  - lib/friendly_routes/services/parser.rb
152
154
  - lib/friendly_routes/services/prefixed_param.rb
153
155
  - lib/friendly_routes/services/prefixed_params.rb