Implementing hypermedia-driven API with Grape (or Sinatra) - ruby-on-rails

I'm trying to implement a hypermedia-driven API using Grape mounted directly on top of Rack. Grape supports presenters ("entities") which
seem to be the proper place for providing all related hypermedia.
If I had Rails router available, I could simply pick route by its ears and toss it into my presenter logic. For example (ROAR approach):
link :self do
article_url(self)
end
But Grape itself doesn't provide easy access to routes, as they have no names or aliases akin to article_url.
Has anybody encountered a similar problem with Grape or Sinatra? Is there a clean and simple way of exposing resource links?

This is possible, but not quite as simply as the Rails url helpers.
From https://github.com/intridea/grape#describing-and-inspecting-an-api:
TwitterAPI::versions # yields [ 'v1', 'v2' ]
TwitterAPI::routes # yields an array of Grape::Route objects
TwitterAPI::routes[0].route_version # yields 'v1'
TwitterAPI::routes[0].route_description # etc.

Related

How do I explicitly set a rails engine routing proxy?

On my Rails 5.0.7 application I have Thredded (0.15.4) mounted as an engine in a namespace.
#routes.rb
namespace :home do
mount Thredded::Engine => "/communities", as: "thredded"
end
This allows me to access /home/communities to pull up the thredded interface.
Unfortunately, this also leads to unexpected behavior. The rails route proxy is not thredded as expected, but rather home_thredded. If I wanted to access a named route inside my engine, I need to do home_thredded.root_path instead of thredded.root_path
This is especially troublesome because thredded.root_path is actually referenced in the code of the thredded gem itself, which now throws an error.
Is there some way to explicitly set the routing proxy to avoid needing to include the namespace in the routing proxy?
A few things that I've considered and rejected:
I could directly edit the code in the offending file of the gem, but that would be annoying to maintain.
I could also write a decorator that overwrites the offending method so that it uses the correct rails routing proxy, but that would still mean that I would have to use the home_thredded.some_path anywhere rather than the expected thredded.some_path
I could not namespace the engine. This could work, but it would break the naming conventions of the rest of the application.
Have you tried:
scope :home do
mount Thredded::Engine => "/communities", as: "thredded"
end
That should add /home to your URI Pattern but leave your Controller#Action and Prefixs unchanged.

Dynamic Sitemap Errors

I'm trying to get dynamic_sitemaps gem to work with my site, but the readme is very technical and a bit over my head at the moment.
I'm running into errors when trying to generate the sitemap for this bit of code.
# You can have multiple sitemaps like the above – just make sure their names are different.
# Automatically link to all pages using the routes specified
# using "resources :pages" in config/routes.rb. This will also
# automatically set <lastmod> to the date and time in page.updated_at:
#
sitemap_for :offers
It's returning the below error
ArgumentError: The collection given to sitemap_for must respond to
find_each. This is for performance. Use Model.scoped to get an ActiveRecord relation that responds to find_each.
I'm looking to have the sitemap contain all my offer posts etc.
Any help is greatly appreciated!
If your model's name is Offer, try
sitemap_for Offer.all
(note: #scoped is deprecated, so #all seems to be the better option going forward)

Inherit from multiple controllers.

Im using a Rails engine as a cms. It all works fine. Im adding devise to this.
My generated devise controllers inherit from Devise::SessionsController. But there are some filters that are run from another controller in the engine that wont run in this case. A lot of the site relies on these filters being run. Of course I could just duplicate them, but thats bad juju.
So my Question is: How can I make one controller run the filters from another? I would prefer not to edit either of the gems.
Multiple inheritance is not supported in Ruby. I think extracting the filters into a module and mixing them in would be the cleanest solution.
See for example:
http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html
There is another option available for Devise: config.parent_controller. It defaults to ApplicationController but can be changed to something else. In my case (a Rails API) I use ApiController. In config/initializers/devise.rb:
Devise.setup do |config|
# ... other configuration options
config.parent_controller = 'ApiController'
end

How to translate a route scope in Rails?

I'm trying to translate the routes in a Rails application. I tried with i18n_routes, but I had some problems with translating actions that didn't depend on a resource. In the end, I solved it without using i18n_routes, as explained here.
The issue now is that I don't find the way to translate scopes. This is my routes.rb:
scope "sport" do
translated_named_route 'it_is_healthy', 'sport#it_is_healthy'
translated_named_route 'it_is_social', 'sport#it_is_social'
end
How to translate sport? I tried with i18n_routes again, but I don't see how to translate the scope. Thanks!
If you are open to using a gem for this, I would recommend using
https://github.com/francesc/rails-translate-routes
The readme is fairly comprehensive and it definitely covers namespaces and scopes in the routes as well.

Rails: Resources_Controller/ Resource_Controller/ Make_Resourceful with Subdomain_Fu

I need to use one of the resourceful controllers plugins - resources_controller/ resource_controller/make_resourceful as I have several polymorphic models and the models have to be either initialized/build depending on the route.
For example:
www.example.com/groups/1/pages
www.example.com/projects/1/pages
where page acts as polymorphic object as both Group and Project have many pages. So I am thinking of using one of the aforementioned plugins to make pages_controller adapt to both routes. All three plugins works fine and differences are just their implementation of recognizing the routes and loading the models based on that.
Now I want to add sub-domain support using Subdomain_fu plugin so the above example would be:
Site1.example.com/groups/1/pages
Site1.example.com/projects/1/pages
Site2.example.com/groups/2/pages
Site2.example.com/projects/2/pages
On looking at all the three plugins, I don't see any way for them to start loading the resources from my subdomain object, as the subdomain is not part of the route. Any advise on what I am trying to accomplish in a dry/restful way?
I don't know how to do that with resources_controller but i was able to pull off the same thing with the inherited_resources plugin.
Here is how i accomplished it:
In my application controller I set up a before_filter to find the subdomain:
def set_subdomain
#subdomain = Subdomain.find_by_url( request.host )
end
Then in my controllers Using inherited resources I set the #subdomain association using the very cool method "begin_of_association_chain"
protected
def begin_of_association_chain
#subdomain
end
Agile web development has great documentation.

Resources