1
votes

Trying to build a route that can display pages with varying information about various types of candy.

the route recognizes URL paths but want it to only show valid candy types e.g kit_kat, gummy_bear, twizzler Any other type of candy specified should generate a 404 status code

Generated a scaffold to allow anyone to add candy types but when i try to pass the valid candy types ( kit_kat etc) I get error

Rails 4.2 NameError in CandiesController#create undefined local variable or method ` params' for #

**candy_controller.rb**

class CandiesController < ApplicationController
  before_action :set_candy, only: [:show, :edit, :update, :destroy]

  # GET /candies
  # GET /candies.json
  def index
    @candies = Candy.all
  end

  # GET /candies/1
  # GET /candies/1.json
  def show
  end

  # GET /candies/new
  def new
    @candy = Candy.new
  end


  # GET /candies/1/edit
  def edit
  end

  # POST /candies
  # POST /candies.json
  def create
    if (([:kit_kat, :skittles, :m_and_ms, :herseys_kiss, :butterfinger, :gummy_bear,
      :twizzler]).any? { |word| params[:title].includes?(word) })


    @candy = Candy.new(candy_params)

    respond_to do |format|
      if @candy.save
        format.html { redirect_to @candy, notice: 'Candy was successfully created.' }
        format.json { render :show, status: :created, location: @candy }
      else
        format.html { render :new }
        format.json { render json: @candy.errors, status: :unprocessable_entity }
      end
   end
 end
  end

  # PATCH/PUT /candies/1
  # PATCH/PUT /candies/1.json
  def update
    respond_to do |format|
      if @candy.update(candy_params)
        format.html { redirect_to @candy, notice: 'Candy was successfully updated.' }
        format.json { render :show, status: :ok, location: @candy }
      else
        format.html { render :edit }
        format.json { render json: @candy.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /candies/1
  # DELETE /candies/1.json
  def destroy
    @candy.destroy
    respond_to do |format|
      format.html { redirect_to candies_url, notice: 'Candy was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private

    def set_candy
      @candy = Candy.friendly.find(params[:id])
    end
    # Use callbacks to share common setup or constraints between actions.


    # Never trust parameters from the scary internet, only allow the white list through.
    def candy_params
      params.require(:candy).permit(:title, :discription)
    end
end

candy.rb

class Candy < ActiveRecord::Base

  extend FriendlyId
  friendly_id :title, use: :slugged 

end

updated candy_controller.rb

    def create
        if candy[:title] && !candy[:title].empty? && [:kit_kat, :skittles, :m_and_ms, :herseys_kiss, :butterfinger, :gummy_bear,
          :twizzler].include?(candy[:title].to_sym)

        @candy = Candy.new(candy_params)

        respond_to do |format|
          if @candy.save
            format.html { redirect_to @candy, notice: 'Candy was successfully created.' }
            format.json { render :show, status: :created, location: @candy }
          else
            format.html { render :new }
            format.json { render json: @candy.errors, status: :unprocessable_entity }
          end
       end
      end
    end

updated code

def create
  if candy_params[:title] && !candy_params[:title].empty? && [:kit_kat, :skittles, :m_and_ms, :herseys_kiss, :butterfinger, :gummy_bear,
      :twizzler].include?(candy_params[:title].to_sym)


    @candy = Candy.new(candy_params)

    respond_to do |format|
      if @candy.save
        format.html { redirect_to @candy, notice: 'Candy was successfully created.' }
        format.json { render :show, status: :created, location: @candy }
      else
        format.html { render :new }
        format.json { render json: @candy.errors, status: :unprocessable_entity }
      end
   end
 end
end
1

1 Answers

2
votes

A couple of things,

First, params doesn't have :title, :title is in params[:candy][:title], or you just use candy_params[:title]

Second, the if statement could be shorter

if candy_params[:title] && !candy_params[:title].empty? && [:kit_kat, :skittles, :m_and_ms, :herseys_kiss, :butterfinger, :gummy_bear,
      :twizzler].include?(candy_params[:title].to_sym)
  (Go on and create the candy)
else
  (Redirect with error messages | Wrong Candy Type)
end

It's always good to check the existence of the params and make sure it's not empty first, then check if it's included in the acceptable list. Notice that your original code was to compare symbol with string, so cast them to the same type and check.

UPDATE

Added else statement for redirect when :title isn't present, empty string, or wrong type