<commit_before># Excursion

[![Gem Version](https://badge.fury.io/rb/excursion.png)](http://badge.fury.io/rb/excursion)
[![Build Status](https://travis-ci.org/markrebec/excursion.png)](https://travis-ci.org/markrebec/excursion)
[![Code Climate](https://codeclimate.com/github/markrebec/excursion.png)](https://codeclimate.com/github/markrebec/excursion)
[![Coverage Status](https://coveralls.io/repos/markrebec/excursion/badge.png?branch=master)](https://coveralls.io/r/markrebec/excursion?branch=master)

Excursion provides a pool of routes into which applications can dump their host information and a basic representation of their routing table, along with javascript URL helpers and [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) configuration to enable cross-origin resource sharing for any of your route endpoints. Other applications configured to use the same route pool can utilize namespaced url helpers for redirecting, drawing links, placing cross-origin XHR requests, etc. between apps. This is extremely useful when multiple applications are sharing a database, authentication, and/or are powered by a shared [rails engine](http://edgeapi.rubyonrails.org/classes/Rails/Engine.html). 

#### Why it's useful

Lets say you have a standalone admin or CMS application running separately from your user-facing frontend application to manage your content, users and other internal concerns. Or maybe you also have discussion forums, a blog, or maybe a knowledge base or help center, all running as a standalone rails applications. These apps would be sharing a database, and would likely be sharing models, authentication/cookies/sessions and other functionality via common gems.

If you wanted to add a link from the admin edit user screen to view a user's profile in the frontend app, you might have to do something like this:

```erb
<%= link_to "view profile", "http://frontend_app.example.com/users/#{@user.username}" %>
```

Maybe you have some default url options setup to help with the host, port, etc., and maybe your `User` model has a `to_param` method defined to return the username and simplify using it in URLs and other places, but it's still not pretty. At the **very best** you're still hardcoding the path, and if that route ever changes in the other application it's unlikely you'll catch it right away for any apps hardcoded like this.

With excursion, once an app has registered itself with the route pool, the above becomes:

```erb
<%= link_to "view profile", frontend_app.user_url(@user) %>
```

If you want to go the other way, and add a link on your user profile pages to ban the user (only for your admins of course!) using an endpoint in the admin app, it's just as easy:

```erb
<%= link_to "ban this user", admin_app.ban_user_url(@user) %>
```

The namespaced url helpers work just like rails built-in helpers, and (using the default configuration) every time an application initializes it will update it's routing table in the pool, so you don't have to worry about maintaining hardcoded paths in your applications. 

Of course, if you change the **name** of the route you'll still have to update any calls to the namespaced `*_url` helpers for that route wherever you're using it, just like you would need to update calls to rails' built-in `*_url` helpers - but when you do make those changes, excursion will complain with a `NoMethodError` just like rails' built-in url helpers would, letting you know what needs to be changed rather than relying on smoke tests or QA to find dead links.

The helper methods are also extremely handy for shared controllers and views. If you've got multiple apps sharing a layout or some templates or partials via a common gem, using the namespaced url helpers within those shared templates ensures links will always point to the correct place no matter what app is currently rendering them.

##### CORS support and javascript helpers

Excursion also provides support for two additional common conerns when navigating cross-application routes: CORS requests and javascript url helpers.  You may optionally include the excursion javascript helpers in your templates, which will provide you with url helper methods in your client-side javascript for all applications in the route pool. And because if you're using the javascript url helpers, it's likely you're making cross-origin XHR requests, excursion also includes optional support for CORS headers and `OPTIONS` requests, with configuration options to control access to your resources.

#### A note about `:format` support

Basically, it's not supported right now.

The issue is being addressed, and you can take a look at [Issue #1](https://github.com/markrebec/excursion/issues/1) for more details or if you'd like to try to help out.

### How it works

When an application registers itself with the route pool, a simple hash of config values and route names & paths (the `/users/:user_id/edit` path spec definitions) for that application are dumped into the pool.
<commit_msg>fixed typo<commit_after># Excursion

[![Gem Version](https://badge.fury.io/rb/excursion.png)](http://badge.fury.io/rb/excursion)
[![Build Status](https://travis-ci.org/markrebec/excursion.png)](https://travis-ci.org/markrebec/excursion)
[![Code Climate](https://codeclimate.com/github/markrebec/excursion.png)](https://codeclimate.com/github/markrebec/excursion)
[![Coverage Status](https://coveralls.io/repos/markrebec/excursion/badge.png?branch=master)](https://coveralls.io/r/markrebec/excursion?branch=master)

Excursion provides a pool of routes into which applications can dump their host information and a basic representation of their routing table, along with javascript URL helpers and [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) configuration to enable cross-origin resource sharing for any of your route endpoints. Other applications configured to use the same route pool can utilize namespaced url helpers for redirecting, drawing links, placing cross-origin XHR requests, etc. between apps. This is extremely useful when multiple applications are sharing a database, authentication, and/or are powered by a shared [rails engine](http://edgeapi.rubyonrails.org/classes/Rails/Engine.html). 

#### Why it's useful

Lets say you have a standalone admin or CMS application running separately from your user-facing frontend application to manage your content, users and other internal concerns. Or maybe you also have discussion forums, a blog, or maybe a knowledge base or help center, all running as a standalone rails applications. These apps would be sharing a database, and would likely be sharing models, authentication/cookies/sessions and other functionality via common gems.

If you wanted to add a link from the admin edit user screen to view a user's profile in the frontend app, you might have to do something like this:

```erb
<%= link_to "view profile", "http://frontend_app.example.com/users/#{@user.username}" %>
```

Maybe you have some default url options setup to help with the host, port, etc., and maybe your `User` model has a `to_param` method defined to return the username and simplify using it in URLs and other places, but it's still not pretty. At the **very best** you're still hardcoding the path, and if that route ever changes in the other application it's unlikely you'll catch it right away for any apps hardcoded like this.

With excursion, once an app has registered itself with the route pool, the above becomes:

```erb
<%= link_to "view profile", frontend_app.user_url(@user) %>
```

If you want to go the other way, and add a link on your user profile pages to ban the user (only for your admins of course!) using an endpoint in the admin app, it's just as easy:

```erb
<%= link_to "ban this user", admin_app.ban_user_url(@user) %>
```

The namespaced url helpers work just like rails built-in helpers, and (using the default configuration) every time an application initializes it will update it's routing table in the pool, so you don't have to worry about maintaining hardcoded paths in your applications. 

Of course, if you change the **name** of the route you'll still have to update any calls to the namespaced `*_url` helpers for that route wherever you're using it, just like you would need to update calls to rails' built-in `*_url` helpers - but when you do make those changes, excursion will complain with a `NoMethodError` just like rails' built-in url helpers would, letting you know what needs to be changed rather than relying on smoke tests or QA to find dead links.

The helper methods are also extremely handy for shared controllers and views. If you've got multiple apps sharing a layout or some templates or partials via a common gem, using the namespaced url helpers within those shared templates ensures links will always point to the correct place no matter what app is currently rendering them.

##### CORS support and javascript helpers

Excursion also provides support for two additional common concerns when navigating cross-application routes: CORS requests and javascript url helpers.  You may optionally include the excursion javascript helpers in your templates, which will provide you with url helper methods in your client-side javascript for all applications in the route pool. And because if you're using the javascript url helpers, it's likely you're making cross-origin XHR requests, excursion also includes optional support for CORS headers and `OPTIONS` requests, with configuration options to control access to your resources.

#### A note about `:format` support

Basically, it's not supported right now.

The issue is being addressed, and you can take a look at [Issue #1](https://github.com/markrebec/excursion/issues/1) for more details or if you'd like to try to help out.

### How it works

When an application registers itself with the route pool, a simple hash of config values and route names & paths (the `/users/:user_id/edit` path spec definitions) for that application are dumped into the pool.

{'fraction_non_alphanumeric': 0.07047581126816643, 'fraction_numerical': 0.00039816842524387816, 'mean_word_length': 4.952014218009479, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 16, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1104000', 'n_tokens_mistral': 2665, 'n_tokens_neox': 2494, 'n_words': 1369}