Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Repository pattern in Ruby

Repository pattern in Ruby

What is a design pattern? What is Repository pattern, when and how should you use it? How does it work? I try to answer these questions in this presentation

Avatar for Gergő Sulymosi

Gergő Sulymosi

February 24, 2015
Tweet

Other Decks in Programming

Transcript

  1. Definition Mediates between the domain and data mapping layers using

    a collection-like interface for accessing domain objects. For humans and railsians:
 Moves #save, #find, #where and co. to a different place.
  2. When should you use it? • Complex storage requirements •

    Using multiple backends/persistency solutions • Swap backends isn’t the intention! (but it makes you capable) • Complicated access rules • If testing your domain objects is too hard* * too hard to fake, stub or setup case the
  3. Business Logic Banana Repository Flat file Database Webservice FileAdapter DatabaseAdapter

    HttpAdapter Flat file Database Webservice Flat file Database Webservice
  4. class  Repo      def  self.adapter        

     @adapter      end      def  self.adapter=(adapter)          @adapter  =  adapter      end      def  self.find(klass,  id)          adapter.find(klass,  id)      end      def  self.all(klass)          adapter.all(klass)      end      def  self.create(object)          adapter.create(object)      end   …   end
  5. class  InMemoryBackend      def  initialize        

     @counter  =  0          @map  =  {}      end      def  create(record)          @counter  =  @counter  +  1          record.id  ||=  @counter          map_for(record)[record.id]  =  record      end      def  find(klass,  id)          map_for_class(klass).fetch  id      end      def  all(klass)          map_for_class(klass).values      end      def  query(klass,  selector)          send  "query_#{selector.class.name.underscore}",  selector      end      private      def  map_for_class(klass)          @map[klass.to_s.to_sym]  ||=  {}      end      def  map_for(record)          map_for_class(record.class)      end   end
  6. module  RepoDelegation      def  save(record)        

     Repo.save(record)      end      def  all          Repo.all  object_class      end      def  find(id)          Repo.find  object_class,  id      end      def  delete(record)          Repo.delete  record      end      def  query(selector)          Repo.query  object_class,  selector      end      private      def  object_class          @object_class  ||=  self.to_s.match(/^(.+)Repo/)[1].constantize      end   end
  7. class  CustomerRepo      extend  RepoDelegation   end   CustomerRepo.all

             #  =>  [#<Customer  id:  “1”>,  …]   CustomerRepo.find(5)  #  =>  #<Customer  id:  “5”> Repo.find(Customer,  5)   Repo.all(Customer)   Repo.create(Cusomer.new(“Budapest.rb”) VS