-1

So I have these 3 models: Coupon, Place, and Category. I want to set up associations such that:

  • Category has both coupons and places associated with it
  • Coupon belongs to several categories
  • Place belongs to several categories.

How would I implement the associations?

What I currently have:

Models

Coupon model
class Coupon < ApplicationRecord
  belongs_to :category
end

Place Model

class Place < ApplicationRecord
  belongs_to :category
end

Category Model

class Category < ApplicationRecord
  has_many :coupons
  has_many :places
end

Controllers: Coupons controller:

class CouponsController < ApplicationController
  before_action :find_coupon, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]

  def index
    if params[:category].blank?
      @coupons = Coupon.all.order("created_at DESC")
    else
      @category_id = Category.find_by(name: params[:category]).id
      @coupons = Coupon.where(category_id: @category_id).order("created_at DESC")
    end
  end

  def show
  end

  def new
    @coupon = Coupon.new
    @categories = Category.all.each do |category|
      category
    end
  end

  def create
    @coupon = Coupon.new(coupon_params)
    if @coupon.save
      redirect_to @coupon
    else
      render 'new'
    end
    @categories = Category.all.each do |category|
      category
    end
  end

  def edit
    @categories = Category.all.each do |category|
      category
    end
  end

  def update
    @categories = Category.all.each do |category|
      category
    end
    if @coupon.update(coupon_params)
      redirect_to @coupon
    else
      render "edit"
    end
  end

  def destroy
    if @coupon.destroy
      redirect_to root_path
    end
  end




  private

  def coupon_params
    params.require(:coupon).permit(:title, :category_id, :description, :company)
  end

  def find_coupon
    @coupon = Coupon.find(params[:id])
  end

end

Places controller:

class PlacesController < ApplicationController
  before_action :set_place, only: [:show, :edit, :update, :destroy]


  def index
    @places = Place.all
  end

  def show
  end

  def new
    @place = Place.new
    @categories = Category.all.each do |category|
      category
    end
  end

  def edit
  end

  def create
    @place = Place.new(place_params)
    respond_to do |format|
      if @place.save
        format.html { redirect_to @place, notice: 'Place was successfully created.' }
        format.json { render :show, status: :created, location: @place }
      else
        format.html { render :new }
        format.json { render json: @place.errors, status: :unprocessable_entity }
      end
    end
    @categories = Category.all.each do |category|
      category
    end
  end

  def update
    respond_to do |format|
      if @place.update(place_params)
        format.html { redirect_to @place, notice: 'Place was successfully updated.' }
        format.json { render :show, status: :ok, location: @place }
      else
        format.html { render :edit }
        format.json { render json: @place.errors, status: :unprocessable_entity }
      end
    end
    @categories = Category.all.each do |category|
      category
    end

  end

  def destroy
    @place.destroy
    respond_to do |format|
      format.html { redirect_to places_url, notice: 'Place was successfully destroyed.' }
      format.json { head :no_content }
    end
    @categories = Category.all.each do |category|
      category
    end

  end

  private

    def set_place
      @place = Place.find(params[:id])
    end

    def place_params
      params.require(:place).permit(:name, :category_id, :description, :address1, :address2, :city, :region, :phone, :email)
    end
end

Views: _sidebar partial:

#sidebar-wrapper
  %ul.sidebar-nav
    %li.sidebar-brand
      %a{:href => root_path}
        Shopperbait
    %li
    - @Category.all.each do |category|
      = link_to category.name, coupons_path(category: category.name)

application.html.haml:

!!!
%html
%head
  %title ""
  %meta{:charset => "utf-8"}/
  %meta{:content => "width=device-width, initial-scale=1, shrink-to-fit=no", :name => "viewport"}/
  %meta{:content => "ie=edge", "http-equiv" => "x-ua-compatible"}
  / Font Awesome
  %link{:crossorigin => "anonymous", :href => "https://use.fontawesome.com/releases/v5.4.2/css/all.css", :integrity => "sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns", :rel => "stylesheet"}


  = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload'
  = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
  = csrf_meta_tags
%body
  = render 'shared/navbar'
  = render 'shared/sidebar'

schema:

ActiveRecord::Schema.define(version: 20181129131201) do

  create_table "categories", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "coupons", force: :cascade do |t|
    t.string "title"
    t.text "description"
    t.string "company"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "category_id"
  end

  create_table "places", force: :cascade do |t|
    t.string "name"
    t.text "description"
    t.string "address1"
    t.string "address2"
    t.string "city"
    t.string "region"
    t.string "phone"
    t.string "email"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "category_id"
  end
end

Also, I would like to be able to show links to the categories in a sidebar. What will be the code for the views? my sidebar doesn't work

  • Welcome to Stack Overflow! This isn't really a code writing service. It is typically helpful if you show what you have already tried and tell us what has worked and hasn't worked. Or, minimally, tell us what you've researched and what has made sense and what is confusing. – jvillian Nov 30 '18 at 15:50
  • i have made an edit to include my current code – Christian Dziwornu Nov 30 '18 at 21:10

1 Answers1

0

You're going to want to start using Ruby on Rails Guides as it covers a lot of the basics, such as Associations. What you're referring to with your above example might be a good use case for a has_many :through Association. There is more detail on the website I linked earlier (Associations).

Regarding your second question and how you'd render links in the sidebar, you will want to iterate through all of the Categories and for each, display a link to that. Looping through records is very basic knowledge. Where is the code that you've written?

VegaStudios
  • 378
  • 1
  • 4
  • 22