Exchange data between Rails Engines - ruby-on-rails

I'm developing a Rails application which uses different Rails Engines to encapsulate functionality.
I want to exchange data between these Engines.
Is there a possibility to create some kind of public interface offered by the Engine to exchange data which I can use in the other engines / the Host Application? Or should I use some kind of JSON API for the access?
Here's a little example which should show what I mean:
Let's assume I have a "full" Rails application. I also have a user-Engine and a tweet-Engine mounted in this application. Now I want to access data from the user in the tweet-Engine.
Btw. Is there furthermore a way to create associations between Engine-Models?
I'm very glad if somebody can help me
Thanks in advance!

There are a few approaches to this. You can have a shared database where engines have models which access the same database to communicate between each other. See the rails guide for more information http://guides.rubyonrails.org/engines.html#using-a-class-provided-by-the-application
The other approach as you said is to build an API, although that it more applicable to separate applications.

in user engine application write controller action which will return xml or json and in tweet engine application just use net:http to get the data by calling the methods of user engine app.
Thank you

Related

How to connect Rails app to a website's API?

I know I'm going to get downvotes for even asking but I honestly have no clue how to do this and any assistance would be appreciated as I have never done this.
I have a client that migrated their blog to HubSpot and would like to have their blog posts displayed on their website. So how do I connect to HubSpot's API to display the blog in their website that I have in a Rails app?
Do I create MVC just for Blog API? Where do I put the URL to connect to?
If you want to connect to an other API the best way to do this is to create service objects. These are plain old Ruby objects (aka PORO) that represent the API as a Ruby object. You are free to use any location you want, but I would stick them in lib/services or app/services. If the provided API uses the Rails (REST) standards than you might be able to use ActiveResource.
You could also look for gems that provide these service objects. A quick RubyGem search finds multiple (unofficial) gems. From witch hubspot-ruby seems the most used and active.
If the gems don't do what you want you could look through the code to find some inspiration and create you own objects. Another option is to fork a project and add the functionality you want.
Here is a link to answer the broader question you're asking: What is the proper "Rails Way" to consume a RESTful web service on another domain?

Do Rails5 API mode app and non API mode app share codes each other?

I'm goint to create a RESTfull service app is made of Rails5 with API mode.
I also need an admin app that provides web views for managing users and contents.
These two apps will share codes each other.
I know a way of creating the API mode app.
$ rails new apiapp --api
How do I create the other project?
The way I would implement this kind of functionality is like so:
RAIL API for your model, database, validation and relationships logic.
Client side MVC for Admin app with RESTful calls. For this I would use Backbone Marionette.
this is the cleanest, least code repetition implementation I can think of, which follows industry standards.
this is as per the software mantra 'consume your own dog food' - if you create an api, use its interface to do your stuff. this way you test and improve it as you go.
If you want RAILS only on both ends, you would be better off implementing your ADMIN and your API as one app, for least code repetition. Create an API controller name space for all your exterior calls, and code normal rails for your admin views and stuff. this way your database and model validation and relationship logic is shared, but controllers and route namespaces are not.
Toodles.
You build the other project as a normal rails project. The thing to understand about Rails 5 api mode is that you cannot have normal html stuff as part of it. The entire rendering pipeline (assets and such) is missing. Rails 5 api mode is fast because big parts of the environment are just plain gone.
What you want to do is have 2 projects:
admin
api
And figure out a way to share your model logic across them.
If you use devise for authentication this is particularly tricky since devise adds things into your user model that you cannot have in an api project. Here's how I got around it:
If Rails.application.class.parent_name == "admin"
# devise crap goes here
end
How exactly you easily share a directory of models across 2 git repos? I have no good answer. I have a rake task which sync's things manually by copying them from the canonical source to the destination but that's a hack.

What would be the best way to use AngularJS with Ruby on Rails?

I'm about to start a new project and I am unsure if using AngularJS for my front end would be a good idea not. I've read about people saying this isn't the smartest way of doing a project. And even if I did, Is there a way to get AngularJS to interact with the controllers? This question may be redundant but I am actually curious of how to effectively do this without it being a waste of time.
I've never completely done it, but I believe the way to go is to build a Rails api and then have a separate Angular project use said api. The api could also be used to build a mobile app. I think the Angular project would still need to be served from a Node.js server in production, but I don't think that would be a big deal.
This is what I used to learn how to build a Rails api: http://apionrails.icalialabs.com/book/chapter_one
You can do it within an existing project and share the models from it.
There are several different approaches to accomplish that. I tried about 5 different guides out there, the best I found (and I finally sticked to) was https://thinkster.io/angular-rails - This guide should help you build a basic CRUD app with angular connected to rails.
You use Rails as an JSON RESTful API which responds to Ajax-Requests (Get, Post, Put, Delete). Angular will handle the frontend stuff - sending those Ajax requests to the routes/methods defined in your rails controllers. So yes, of course your AngularJS app can interact with your rails controllers.
This also helped me to understand the setup in the beginning: Instead of the Rails View, you will be using AngularJS as your view:
I really love using angular with rails, because setting up the JSON responses (especially with Active Model Serializer Gem) is very easy and quickly done. i deffinitely can recommend it, and I have not encountered any unsolvable problems - so far.
Just go trough this guide I linked and you will see if this setup fits your needs.
The short answer is that your Rails application will have to present some kind of a public API for your AngularJS application to consume. Angular (and it's brethren, like React and Ember) runs client-side, on the browser, and it needs "something" to make AJAX calls against. That "something", i.e. your backend, can be Firebase, Parse, AWS Lambdas, Rails API, etc. Since you already have a Rails application, it probably makes the most sense to add some RESTful API endpoints that use the existing models (and possibly controllers) to consume/produce JSON payloads from/for the client.

Searching WordPress blog from Rails app

I have a site-wide custom written search controller for my Rails 3 app and would like to include results from the site's WordPress blog. What is the best way for me to perform a keyword search on posts from within my Rails app?
If you share database then just use SQL query on it. This solution gives you speed of direct db query but you’ll need to construct that query properly in order to get all relevant data.
If you don't have access to the WP database from your Rails app then the best way will be to use curl, httparty, RestClient or any other file retrieval library.
To do that, create Wordpress page with custom template which will output search results in a format which is best for you to parse in Rails app (json, xml, csv, urlencoded, whatever).
Then request that WP page from your Ruby app using curl/RestClient/httparty…
This solution gives you the power of WP template tags and functions to get the results.
Also instead of creating custom template from scratch you can just simply copy and tweak search.php from core template to provide the results in a format required by your Rails app.
With this solution you are lacking the speed of direct access to db because all search result will have to be transferred through http pipe and you have to process the data twice (encode to the proper format in WP and decode in Rails app).
Interesting problem. I think I would approach it like this:
Use RSS as the text transport from the blog to your rails app. This allows the flexibility to add more blogs in the future, change your blog engine, database host, etc. It also protects you from Wordpress code updates. Given the security history of Wordpress, I like to host them in a protected sandbox anyway. RSS is the native language for blogs, so it seems a natural fit for this kind of content integration.
Use the feedzirra gem to import RSS entries into a rails model.
Use Elasticsearch and tire for fuzzy text searching across both your rails app and your blog entries. See this Railscast for details.
Option 1. is to use search engine for both sites, like elasticsearch, solr etc. So you populate the index from rails and wordpress.
Option 2. You write script, that reads periodically your wordpress RSS and saves data in your rails app.
At the end you should avoid to search from different sources, you should gather the data into one place and then search.
You don't have to stuck with wordpress. You can use Google search APIs. Web search api has been deprecated but still working. Its replacement is Custom Search API. You may need to pay if you query over the limit.
Alternatively you can leverage other search engine APIs like Bing Search API.
I'd suggest using the Wordpress JSON API and plugging that into your search using solr or something similar. You can index as posts are created and then call the articles via the sam JSON interface.
Use Tire and wp-elasticsearch with ElasticSearch.

Distributed Resource in Rails

I am planning a system that requires collaboration between many local Rails apps. The design calls for a global app to relay RESTful requests between these servers.
For example, imagine each school having a local Rails app, including a Teacher resource. I propose a global app which provides access to teachers as: /school/42/teacher/3
The School resource on the global server has a field for the base URL of the app at each school, so it can relay such a request to school_42_url/teacher/3.
The design calls for relaying, rather than having school servers connecting directly to each other.
I can think of several ways to achieve this but, being new to Rails, can't work out which one is 'the Rails way'.
ActiveResource is appealing, but seems to require a fixed 'site' rather than setting it for each request.
Routing, perhaps with URL globbing might work, but I need to see an example of how to achieve this.
A third approach would be a custom Controller, but this doesn't feel like the Rails way.
To be clear, the combination of {school_id, teacher_id} is globally unique, but the global server need not store details of teachers, those are treated as a web resource.
Comments or suggestions welcome.
You should use rails RESTful architecture on your client apps to expose apis (xml, json), and some library like Net::HTTP to call those apis from your server(main) app.
It sounds like Pow may be what your looking for. It allows you to configure URL's for stack and rails application via symbolic links. It fits well in the rails model and may allow you to build your independent RESTful applications in the manor specified. I know their are methods for having independent rails servers work together but based this is a very low overhead approach and may be the way to go at-least for testing and development purposes.

Resources