Rails Many-to-Many Relationships

09 Dec, 2018

Categories back end dev

Rails Categories

A rails store with shopping cart, stripe checkout, and social oauth. Confirmation emails also. The goal is to easily combine this bit with other snippets.

Setup

rails new <app name> --database=postgresql

Postgres

Using the custom multiple database postgres docker image:

docker run -id --name rails-db -e POSTGRES_MULTIPLE_DATABASES="railyard-dev","railyard-test","railyard-prod" -e POSTGRES_USER=<database user> -e POSTGRES_PASSWORD=<password> -p 5434:5432 db:latest

Rails

has_many

Create two models, for product and category (both singular, rails will generate the plural), or anything else you may want to call them.

Migrations:

#create_product_categories
class CreateProductsCategories < ActiveRecord::Migration[5.2]
  def change
    create_table :products_categories do |t|
      t.belongs_to :product, index: true
      t.belongs_to :category, index: true
      t.timestamps
    end
  end
end

Models:

#/app/models/product.rb
class Product < ApplicationRecord
    has_many :products_categories
    has_many :categories, through: :products_categories
    has_many_attached :images   # active storage
end

class Category < ApplicationRecord
    has_many :products_categories
    has_many :products, through: :products_categories
end

Controllers:

#products_controller
# Update these:

# GET /products/new
def new
    @product = Product.new
    @category = @product.categories.build
end

# POST /products
# POST /products.json
def create
  @product = Product.new(product_params)

  respond_to do |format|
    if @product.save
        product_params[:category_id].split(',').each do |it|
            puts "CAT SAVED"
            @product.categories.create(:name => it.strip, :description => "Just a test")
        end

      format.html { redirect_to @product, notice: 'Product was successfully created.' }
      format.json { render :show, status: :created, location: @product }
    else
      format.html { render :new }
      format.json { render json: @product.errors, status: :unprocessable_entity }
    end
  end
end


Back