Search code examples
rubyohm

Ruby Ohm, how to find a record in a set or collection?


This question is related to other: Many-to-many relationships with Ruby, Redis, and Ohm

I have a Model with a collection and I would like to look for an id. How can I do this?

Models

class User < Ohm::Model
    attribute :name
end

class Event < Ohm::Model
    attribute :title
    collection :attendees, :User
end

Usage

@fran = User.create(name: "Fran")
@event = Event.create(title: "Party in Las Vegas")
@event.attendees.add(@fran)

Event.find(attendees: @fran)
=> Ohm::IndexNotFound exception!

What I would like is to be able to ask by the Users which attending of a Event and what are the Events by an User.


Solution

  • You want a set of all users attending an event, and you also want a set of all events attended by a user. The simplest way would be to create a model Attendee that references both a user and an event:

    class Attendee < Ohm::Model
      reference :user, :User
      reference :event, :Event
    end
    
    u = User.create(name: "foo")
    e = Event.create(name: "bar")
    
    a = Attendee.create(user: u, event: e)
    
    Attendee.find(user_id: u.id).include?(a)  #=> true
    Attendee.find(event_id: e.id).include?(a) #=> true
    

    Then if you want all users that attended an event:

    Attendee.find(event_id: e.id).map(&:user)
    

    Or all the events attended by a user:

    Attendee.find(user_id: e.id).map(&:event)
    

    You can create methods in User and Event as shortcuts for those finders:

    class User < Ohm::Model
      attribute :name
    
      def events
        Attendee.find(user_id: id).map(&:event)
      end
    end
    
    class Event < Ohm::Model
      attribute :name
    
      def visitors
        Attendee.find(event_id: id).map(&:user)
      end
    end
    

    Then:

    u.events.include?(e)   #=> true
    e.visitors.include?(u) #=> true
    

    Let me know if it works for your use case.