Richlewis
Richlewis

Reputation: 15374

Access attribute on has_many through

Every time I revisit this query it confuses me, and I'm looking for a more thorough understanding.

I have

class Image < ActiveRecord::Base
  has_many :image_categories, dependent: :destroy
  has_many :categories, through: :image_categories
end

class PagesController
  def portfolio
    @images = Image.all
  end
end

In my view then I want to show all my images and then print out each category name as a class name

<%= @images.each do |i| %>
  <div id="item-1" class="isotope-item ok-md-3 ok-xsd-12 ok-sd-6 ## class names here">
    <%= image_tag(i.photo.url(:image_square_home)) %>
 </div>

Upvotes: 0

Views: 49

Answers (3)

Ioannis Tziligkakis
Ioannis Tziligkakis

Reputation: 711

You can handle this in a helper file (e.g. PagesHelper in order to keep your views and models as clean as possible. It could look like this:

# app/helpers/pages_helper.rb    
module PagesHelper
  def image_classes(image)
    %w(isotope-item ok-md-3 ok-xsd-12 ok-sd-6) + categories_names(image)    
  end

  private

  def categories_names(image)
    image.categories.pluck(:name)
  end
end

# app/views/pages/portfolio.rb
<%- @images.each do |image| %>    
  <%= div_for image, class: image_classes(image) do |img| %>
    <%= image_tag img.photo.url(:image_square_home) %>
  <%= end %>
<% end %>

Upvotes: 1

ConnorCMcKee
ConnorCMcKee

Reputation: 1645

You want to use the following code:

<%= i.categories.pluck(:name).join %>

This will grab the name of every category associated with the current image into an array, and then join them together into a single string separated by spaces.

In practice, it will look like this:

<div id="item-1" class="isotope-item ok-md-3 ok-xsd-12 ok-sd-6 <%= i.categories.pluck(:name).join %>">
    <%= image_tag(i.photo.url(:image_square_home)) %>
</div>

Upvotes: 1

vich
vich

Reputation: 11896

Since you want to add multiple class names to your div, try this:

<div id="item-1" class="isotope-item ok-md-3 ok-xsd-12 ok-sd-6 <%= i.categories.pluck(:name) %>">

You may want to use the try method if an image could have no categories:

<%= i.categories.try(:pluck, :name) %>

Upvotes: 1

Related Questions