Class: Cybertrain::Gen::Mapper

Inherits:
Object
  • Object
show all
Defined in:
cybertrain/generator/routes_dsl.rb

Overview

The receiver of the routes DSL. Routes.draw evaluates its block with the mapper as self; blocks nested inside it (resources, member, collection) take the mapper as their argument instead (resources :posts do |posts| posts.resources :comments end), see Routes.draw for why.

The methods available in config/routes.rb. They run when spin run gen generates gen/routes.rb, not in the server, so a mistake is an ArgumentError from spin run gen. Routes match in the order drawn; HEAD matches GET routes; an unmatched request is a plain 404 Not Found.

Each named route gets a <name>_path and a <name>_url helper (see Gen::UrlHelpers). Not available: resource (singular), match, namespace, scope, constraints, mount, formats, globs and optional segments.

Instance Method Summary collapse

Instance Method Details

#collection {|mapper| ... } ⇒ nil

Inside resources: get “search” -> GET /posts/search as search_posts.

Yield Parameters:

Returns:

  • (nil)

Raises:

  • (ArgumentError) —

    outside a resources block



248
249
250
# File 'cybertrain/generator/routes_dsl.rb', line 248

def collection(&block)
  within("collection", block)
end

#delete(path, to: "", as: "") ⇒ nil

A DELETE route; see #get.

Parameters:

  • path (String)
  • to (String) (defaults to: "")
  • as (String) (defaults to: "")

Returns:

  • (nil)


148
149
150
# File 'cybertrain/generator/routes_dsl.rb', line 148

def delete(path, to: "", as: "")
  add_custom_route("DELETE", path, to, as)
end

#get(path, to: "", as: "") ⇒ nil

A GET route. At the top level to: is required; inside a resources block (or its member / collection) the controller is the resource’s and the action defaults to the path.

The name is as:, or the path with every character outside [a-z0-9_] turned into _ ("about-us" → about_us). Inside a member block it gets the resource’s singular as a suffix (preview_post), inside collection the plural (search_posts), inside resources its prefix (post_...).

Examples:

get "/about", to: "pages#about"               # GET /about, about_path
get "/feed", to: "articles#index", as: "feed"   # feed_path

Parameters:

  • path (String) —

    :name segments become params ("/users/:id")

  • to (String) (defaults to: "") —

    "controller#action", or just "action"

  • as (String) (defaults to: "") —

    the route name

Returns:

  • (nil)

Raises:

  • (ArgumentError) —

    with no controller, an invalid or duplicate name



108
109
110
# File 'cybertrain/generator/routes_dsl.rb', line 108

def get(path, to: "", as: "")
  add_custom_route("GET", path, to, as)
end

#member {|mapper| ... } ⇒ nil

Inside resources: get “preview” -> GET /posts/:id/preview as preview_post.

Yield Parameters:

Returns:

  • (nil)

Raises:

  • (ArgumentError) —

    outside a resources block



239
240
241
# File 'cybertrain/generator/routes_dsl.rb', line 239

def member(&block)
  within("member", block)
end

#patch(path, to: "", as: "") ⇒ nil

A PATCH route; see #get.

Parameters:

  • path (String)
  • to (String) (defaults to: "")
  • as (String) (defaults to: "")

Returns:

  • (nil)


128
129
130
# File 'cybertrain/generator/routes_dsl.rb', line 128

def patch(path, to: "", as: "")
  add_custom_route("PATCH", path, to, as)
end

#post(path, to: "", as: "") ⇒ nil

A POST route; see #get.

Parameters:

  • path (String)
  • to (String) (defaults to: "")
  • as (String) (defaults to: "")

Returns:

  • (nil)


118
119
120
# File 'cybertrain/generator/routes_dsl.rb', line 118

def post(path, to: "", as: "")
  add_custom_route("POST", path, to, as)
end

#put(path, to: "", as: "") ⇒ nil

A PUT route; see #get.

Parameters:

  • path (String)
  • to (String) (defaults to: "")
  • as (String) (defaults to: "")

Returns:

  • (nil)


138
139
140
# File 'cybertrain/generator/routes_dsl.rb', line 138

def put(path, to: "", as: "")
  add_custom_route("PUT", path, to, as)
end

#resources(name, only: nil, except: nil) {|mapper| ... } ⇒ nil

The seven standard actions (only:/except: pick some). Routes drawn in the block (nested resources, member, collection) come first, so /posts/search wins over /posts/:id as in Rails.

resources :articles draws, to ArticlesController:

Verb Path Action Helper
GET /articles index articles_path
POST /articles create  
GET /articles/new new (def new_action) new_article_path
GET /articles/:id/edit edit edit_article_path(article)
GET /articles/:id show article_path(article)
PATCH, PUT /articles/:id update  
DELETE /articles/:id destroy  

A word that is its own plural (sheep) names the collection sheep_index. Nested resources take the parent’s id as :<singular>_id and its singular as a name prefix: article_comments_path(article), article_comment_path(article, comment). Their controller is the child’s (CommentsController).

Examples:

resources :articles do |articles|
  articles.resources :comments, only: [:create, :destroy]
  articles.member { |m| m.get "preview" }        # GET /articles/:id/preview, preview_article_path
  articles.collection { |c| c.get "search" }     # GET /articles/search, search_articles_path
end

Parameters:

  • name (Symbol) —

    the plural (:articles)

  • only (Array<Symbol>, nil) (defaults to: nil) —

    draw only these actions

  • except (Array<Symbol>, nil) (defaults to: nil) —

    draw all but these

Yield Parameters:

  • mapper (Mapper) —

    the mapper, to call with an explicit receiver inside the block (articles.resources): Spinel gives a nested block no implicit self

Returns:

  • (nil)


187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'cybertrain/generator/routes_dsl.rb', line 187

def resources(name, only: nil, except: nil, &block)
  # Interpolated, not name.to_s: in a program that also loads the model
  # runtime, name.to_s came out boxed and widened @controller, which
  # broke the C build of save_scope/restore_scope.
  plural = "#{name}"
  singular = Inflector.singularize(plural)
  collection_path = "#{@path_prefix}/#{plural}"
  member_path = "#{collection_path}/:id"
  member_name = @name_prefix + singular
  # A word whose singular is itself (sheep, news) would give index and
  # show the same name; Rails names the collection news_index.
  collection_name = @name_prefix + plural + (singular == plural ? "_index" : "")

  unless block.nil?
    saved = save_scope
    @mode = "resources"
    @path_prefix = "#{collection_path}/:#{singular}_id"
    @name_prefix = member_name + "_"
    @controller = plural
    @member_path = member_path
    @member_name = member_name
    @collection_path = collection_path
    @collection_name = collection_name
    block.call(self)
    restore_scope(saved)
  end

  used = []
  STANDARD_ACTIONS.each do |action|
    next unless only.nil? || only.include?(action)
    next if !except.nil? && except.include?(action)

    case action
    when :index then add_standard(used, "GET", collection_path, plural, "index", collection_name)
    when :create then add_standard(used, "POST", collection_path, plural, "create", collection_name)
    when :new then add_standard(used, "GET", "#{collection_path}/new", plural, "new", "new_#{member_name}")
    when :edit then add_standard(used, "GET", "#{member_path}/edit", plural, "edit", "edit_#{member_name}")
    when :show then add_standard(used, "GET", member_path, plural, "show", member_name)
    when :update
      add_standard(used, "PATCH", member_path, plural, "update", member_name)
      add_standard(used, "PUT", member_path, plural, "update", member_name)
    when :destroy then add_standard(used, "DELETE", member_path, plural, "destroy", member_name)
    end
  end
  nil
end

#root(to) ⇒ nil

root “posts#index” -> GET / named “root”.

Parameters:

  • to (String) —

    "controller#action"

Returns:

  • (nil)


85
86
87
88
# File 'cybertrain/generator/routes_dsl.rb', line 85

def root(to)
  target = split_to(to)
  add_spec("GET", "/", target[0], target[1], "root")
end