ruby-on-railsperformanceactiverecorddistributed-systemmulti-tier

How to make ActiveRecord query faster on production environment running multiple servers?


How could I rewrite the ActiveRecord query to solve this issue? Im a python programmer and use sqlalchemy, so it would be great if this could be explained from a python perspective. I really just need an idea of how to go about this problem.

I know the issue probably has to do with the connection being opened on every server, hence the slowness when run in production environment compared to single server staging environment. But I dont know how to go about this problem. I'm used to programming in python, where I use sqlalchemy, which is already optimized for this sort of distributed system.

class Board < ActiveRecord::Base
    def messages
        message_ids = Message.where("board_id = ?", self.id).map { |c| c.id }
        message_ids.map { |message_id| Message.find_by_id(message_id) }
    end
end

The ActiveRecord query is optimized to run on both multi-server production and single-server staging environments.


Solution

  • app/models/board.rb

    class Board < ActiveRecord::Base
      has_many :messages
    end
    

    Above will allow you to do something like:

    board = Board.first
    board.messages
    # => returns a `ActiveRecord::Associations::CollectionProxy` object
    #    for beginners, simply treat `ActiveRecord::Associations::CollectionProxy` as
    #    if that's an Array object. So you can still do something like
    
    board.messages.first
    # => #<Message id: 123, ...>
    

    app/models/message.rb

    class Message < ActiveRecord::Base
      belongs_to :board
    end
    

    ...which will allow you to do:

    message = Message.first
    message.board
    # => #<Board id: 456, ...>
    

    See Rails association docs here

    In particular, take note of "implied conventions", like implied foreign_key and class_name values