arnaudjnn
arnaudjnn

Reputation: 1063

Tag model on another Rails

I want to tag my product model on my post model.

post.rb

 has_many :taggings
 has_many :products, through: :taggings

product.rb

has_many :taggings
has_many :posts, through: :taggings

tagging.rb

belongs_to :post
belongs_to :product

On my post view, I have a product list. I want that when the user clicks on a product, it creates a new product/post link via post method.

What link can I use? How to set up controllers and params?

Thanks for the help

Upvotes: 0

Views: 306

Answers (1)

max
max

Reputation: 102001

If you want to let the user create multiple taggings at once you can just add a select / checkbox to the forms for a post.

<%= form_for(@post) do |f| %>
  # ...
  <div class="field">
    <%= f.label :product_ids %>
    <%= f.collection_select :product_ids, Product.all, :name, :id %>
  </div>
<% end %>

def post_params
  params.require(:post)
        .permit(:foo, :bar, product_ids: [])
end

Rails will automatically create the records in the join table.

If you want the user to create the linkings one by one you need to setup a nested route:

Rails.application.routes.draw do
  # ...
  resources :posts do
    resources :taggings, only: :create
  end
end

You then need to setup a form for each product on the posts/show.html.erb page:

<ul>
  <% @post.products.each do |product| %>
    <li>
    <%= product.name %>
    <%= form_for [@post, product.taggings.new] do |f| %>
      <%= f.hidden_field :product_id %>
      <%= f.submit 'tag' %>
    <% end %>
    </li>
  <% end %>
</ul>

You can pretty this up later with CSS/JS.

And a controller to handle creating the taggings.

class TaggingsController < ApplicationController
  # POST /posts/:post_id/taggings
  def create
    @post = Post.find(params[:post_id])
    @tagging = @post.taggings.new(product: Product.find(params[:tagging][:product_id]))
    if @tagging.save
      redirect_to @product, success: 'Tagging saved.'
    else
      redirect_to @product, error: 'Tagging not saved.'
    end
  end
end

Upvotes: 1

Related Questions