Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I serialize and communicate ActiveRecord instances across identical Rails apps?

The main idea is that I have several worker instances of a Rails app, and then a main aggregate

I want to do something like this with the following pseudo pseudo-code

posts = Post.all.to_json( :include => { :comments => { :include => :blah } })
# send data to another, identical, exactly the same Rails app

# ...
# Fast forward to the separate but identical Rails app:
# ...

# remote_posts is the posts results from the first Rails app
posts = JSON.parse(remote_posts)  
posts.each do |post|
  p = Post.new
  p = post
  p.save
end

I'm shying away from Active Resource because I have thousands of records to create, which would mean thousands of requests for each record. Unless there is a way to do it all in one request with Active Resource that is simple, I'd like to avoid it.

  • Format doesn't matter. Whatever makes it convenient.
  • The IDs don't need to be sent, because the other app will just be creating records and assigning new IDs in the "aggregate" system.
  • The hierarchy would need to be preserved (E.g. "Hey other Rails app, I have genres, and each genre has an artist, and each artist has an album, and each album has songs" etc.)
like image 855
Blaine Lafreniere Avatar asked Feb 28 '23 12:02

Blaine Lafreniere


1 Answers

There are several options you could implement to get this to work:

Active Resource

As others have answered, you could make use of ActiveResource. After reading your comments, this seems like a solution you'd like to steer clear of due to the multiple-request aspect

Receiving Controller

You could have a controller in your second rails application that receives data and creates records out of it.

class RecordReceiver < ActiveRecord::Base
  def create
    params[:data][:posts].each do |p|
      Post.create(p)
    end
  end
end

You could namespace this controller inside an "API" namespace, which is a rather clean solution if implemented properly.

Share the Database

You could share one database across two applications. This means you won't need to send the data from one model to another, it will already be there. This is the least amount of work for you as a developer, but may not be possible depending on the system architecture you have.

Two databases in each application

You could implement multiple database in each application, like so:

#Add to database.yml
other_development:
  adapter: mysql
  database: otherdb_development
  username: root
  password:
  host: localhost

other_production:
  adapter: mysql
  database: otherdb_production
  username: root
  password:
  host: localhost

Then, define your models like so:

class Post < ActiveRecord::Base

end

class PostClone < ActiveRecord::Base
  establish_connection "other_#{RAILS_ENV}"
end

Now, your Clone model will point to the current database, and the PostClone model will point to the other database. With access to both, you can copy the data over whenever you need to with basic model methods.

Conclusion

Since you don't want to use ActiveResource, I would recommend that you simply share the database between the applications. If this isn't a possibility, then try having two models, each going to a different database. Finally, the receiving controller is a valid, albeit slower option (as it needs to do the HTTP request on top of the database requests)

like image 64
Mike Trpcic Avatar answered May 01 '23 04:05

Mike Trpcic