I have 2 Ruby on Rails 4 apps on the same server (they do not - and should not - share database):
deploy@Ubuntu-1404-trusty-64-minimal:~/applications$ ls
app1 app2
How do I exchange data between app1 and app2?
My current implementation is unstable and not secure:
app1 requests app2 to update first and last name of the user with username bobby
:
# app1
HTTParty.get("https://app2.com/update_full_name?username=bobby&first_name=Bob&last_name=Dylan")
app2 receives app1's request and processes:
# app2 app/controllers/some_controller.rb
def update_full_name
user = User.find_or_create_by(username: params[:username])
user.update_attributes(first_name: params[:first_name], last_name: params[:last_name])
end
I have read that ActiveResource has been removed from Rails 4. I never really understood ActiveResource anyway, so I will not explore it further and will prefer a different solution.
I had the same problem and explored every option: ActiveResource (which is deprecated), callbacks with my own homegrown API wrappers, queueing with Redis or RabbitMQ. Nothing was easy enough for my simple mind to implement. If Model1
in App1
will always update Model2
in App2
, then best solution I've found with Rails is the Promiscuous gem
It's makes it pretty simple to run a pub/sub system that keeps data synched up between two ruby/rails apps. It works with both ActiveRecord & Mongoid. The documentation goes into more depth, but here are a few gotchas I found when trying to set it up using the Quick Start guide on the github page.
If using ActiveRecord on the publisher side, you will need to create a new table (subscriber does not need this table to my knowledge):
create_table :_promiscuous do |t|
t.string :batch
t.timestamp :at, :default => :now
end
You will also need to add a column to every publisher and subscriber model
# in App1 - publisher
add_column :publisher_model, :_v, :integer, limit: 8, default: 1
# in App2 - subscriber
add_column :subscriber_model, :_v, :integer, limit: 8
You can set the name of the published model. For example if I have a namespaced class Admin::User
in App1, I can publish the attributes :as => 'AdminUser'
and App2 has the model AdminUser
it will listen correctly.
I'm finding more and more ways to use this setup. Gives me a lot more flexibility with sharing and managing my data. Good luck.