Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tagging example #215

Open
scalp42 opened this issue Sep 30, 2016 · 5 comments
Open

Tagging example #215

scalp42 opened this issue Sep 30, 2016 · 5 comments

Comments

@scalp42
Copy link

scalp42 commented Sep 30, 2016

In the tagging example, we can find posts having a certain tag with this:

Post.find(tag: 'tagging')

Now how would someone be able to get the posts matching a tag (pretty much reversed logic) ?

I'm assuming you would need a reference in the Tag model to the Post model but I can't quite figure it in the Ohm way:

class Tag < Ohm::Model
  counter :total
  reference :posts, :Post

# How would you query Tag model after that to find the posts associated ?

Any chance it could be added to the example ?

Thanks a lot!

@soveran
Copy link
Owner

soveran commented Oct 1, 2016

@scalp42 I don't use a Tag model, so for me if I have a tag t, I do Post.find(tag: t) as you described. What kinds of features do you expect a Tag model to provide? I see you want to have counters, for example, and a reference to Post. Would it be polymorphic? What about new tags: are users allowed to create new tags or they are created by you beforehand? There are ways to implement all those features, but each approach is slightly different. Let me know.

@scalp42
Copy link
Author

scalp42 commented Oct 1, 2016

I think I'm trying to figure the many-to-many relationship with Ohm in the case of Post having multiple Tag and Tag belonging to multiple Post if it make sense ?

Thanks a lot for the quick answers as always, greatly appreciated.

@soveran
Copy link
Owner

soveran commented Dec 1, 2016

@scalp42 Looking back at this issue, did you find a way to do what you needed? If not, let me know and I'll work on an example.

@scalp42
Copy link
Author

scalp42 commented Dec 14, 2016

Let's assume a vendor (Google), having multiple users subscribed to its paying products (Youtube, Music, etc), the models would like like this:

class User < Ohm::Model
  attribute :name
end

class Subscription < Ohm::Model
  reference :user, :User
  reference :product, :Product
end

class Product < Ohm::Model
  attribute :name
  reference :vendor, :Vendor
end

class Vendor < Ohm::Model
  attribute :name
  collection :products, :Product
end

Now let's create an user, a vendor and a product to match the description above:

user = User.create(name: '[email protected]')

vendor = Vendor.create(name: 'google')

product = Product.create(name: 'youtube', vendor: vendor)

Now we want to have our user John subscribed to Youtube:

Subscription.create(user: user, product: product)

Let's assume that we have dozen of users, vendors, products and subscriptions that go with it. We can query our "join table" to get the exact info we need:

# This would return all the users subscribed to the "youtube" product
Subscription.find(product_id: product.id).map(&:user)

# This would return all products that a particular user "John" is subscribed to:
Subscription.find(user_id: user.id).map(&:product)

# Which then could also returns all the vendors user "John" is subscribed to:
Subscription.find(user_id: user.id).map(&:product).map { |p| p.vendor.name }
=> ["google"]

Couple extras to help understand references relation:

Product.all.first
=> #<Product:0x007fa303991698 @_memo={}, @attributes={:type=>"youtube", :vendor_id=>"1"}, @id="1">

Subscription.find(user_id: user.id).first
=> #<Subscription:0x007fa3033a3bf0 @_memo={}, @attributes={:user_id=>"1", :product_id=>"1"}, @id="1">

Subscription.find(user_id: user.id).first.product
=> #<Product:0x007fa303307a48 @_memo={}, @attributes={:type=>"youtube", :vendor_id=>"1"}, @id="1">

Product.find(vendor_id: vendor.id).first
=> #<Product:0x007fa3032bea50 @_memo={}, @attributes={:type=>"youtube", :vendor_id=>"1"}, @id="1">

Product.find(vendor_id: vendor.id).first.vendor
=> #<Vendor:0x007fa3031b4d58 @_memo={}, @attributes={:name=>"google"}, @id="1">

Product.find(vendor_id: vendor.id).first.vendor.products.first
=> #<Product:0x007fa30357b1a8 @_memo={}, @attributes={:type=>"youtube", :vendor_id=>"1"}, @id="1">

Vendor.all.first
=> #<Vendor:0x007fa30190f1b8 @_memo={}, @attributes={:name=>"google"}, @id="1">

Vendor.all.first.products.first
=> #<Product:0x007fa303aa1b50 @_memo={}, @attributes={:type=>"youtube", :vendor_id=>"1"}, @id="1">

One thing to note is that when you write:

class Subscription < Ohm::Model
  reference :user, :User
  reference :product, :Product
end

The reference actually creates an index that you can query with an id hence:

Subscription.find(product_id: product.id)

Hopefully it helps others @soveran, thanks again for the help and sorry for the delay!

@soveran
Copy link
Owner

soveran commented Dec 14, 2016

@scalp42 That's excellent! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants