1

I have a user model that has many photos and those photos have many tags.

My routes:

resources :users do
  resources :photos do  
    resources :tags
  end
end

My view:

<%= @user.photos.tags.count %>

I don't know how to retrieve all the tags a user has, since it's a 2nd level nested resource. Any idea? Thanks guys!

Gibson
  • 2,055
  • 2
  • 23
  • 48
  • You can do it this way: `Tag.includes(photos: :user).where(users: { id: current_user.id }).count` – MrYoshiji May 26 '14 at 20:38
  • Isin't that too much logic for the view? – Gibson May 26 '14 at 20:41
  • @MrYoshiji Or is this suposed to be a new scope in the user model? – Gibson May 26 '14 at 20:43
  • Following the Rails Style Guide (https://github.com/bbatsov/rails-style-guide), you should never have to write any model's name inside a view. It is very relative, I always use it, but the spirit here is more like "never make a query in the view, do it in the controller". In your case I would create a scope in the User model, something like `scope :tags_through_photos, ->(user) { Tag.includes(photos: :user).where(users: { id: user.try(:id) || user }) }` – MrYoshiji May 26 '14 at 20:47
  • What exactly don't you know: how to construct an URL or just retrieve tags for users? – Sergey Alekseev May 26 '14 at 20:49
  • Actually since this is going to be used a lot it should either be a method on User model or better a counter cache – Mike Szyndel May 26 '14 at 20:49
  • Retrieve tags from users... – Gibson May 26 '14 at 20:49

2 Answers2

2

Here you go:

class User < ActiveRecord::Base
  has_many :photos, dependent: :destroy
  has_many :tags, through: :photos
end

class Photo < ActiveRecord::Base
  belongs_to :user
  has_many :tags, dependent: :destroy
end

class Tag < ActiveRecord::Base
  belongs_to :photo
end

# @user.tags

Just scroll to the end of http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association.
By the way, don't be confused with nested resources and associations as terms.

Sergey Alekseev
  • 11,910
  • 11
  • 38
  • 53
2

You can do:

class User < ActiveRecord::Base 
  has_many :photos
  has_many :tags, through: :photos
end

And at the view:

<%= @user.tags.count %>
Ricardo Nacif
  • 508
  • 4
  • 12