1
votes

I want to use find_or_create method in my game dates controller. I don't know how to use that method in create action, when params are in game_date_params. Any suggestion how can I extract date from game_date_params?

class GameDatesController < ApplicationController
  before_action :authenticate_user!
  before_action :authenticate_admin

  def index
    @game_dates = GameDate.all
    @showcases  = Showcase.joins(:game_dates)
  end

  def new
    @game_date = GameDate.new
    @game_date.referee_stats.build
  end

  def create
    @game_date = GameDate.new(game_date_params)
    if @game_date.save
      redirect_to showcases_path
      flash[:success] = "Game date created"
    else
      render 'new'
    end
  end

  def show
    @game_date = GameDate.find(params[:id])
  end

  def destroy
    @game_date = GameDate.find(params[:id]).destroy
    redirect_to root_url
    flash[:success] = "Game date deleted"
  end


  private

  def game_date_params
    params.require(:game_date).permit(:date, referee_stats_attributes: [ :games_count, :showcase_id ])
  end

This is output from POST action:

Started POST "/game_dates" for 127.0.0.1 at 2016-04-01 10:21:44 +0200 Processing by GameDatesController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"jmuOmMCO/WTFIkxrsw5l2cPVMqZAl7h11f281I+OyoHH3ddwKoB9ANAqvQEHulR88c7fzQXnnIaxs8FChMCjqw==", "game_date"=>{"date(1i)"=>"2016", "date(2i)"=>"4", "date(3i)"=>"1", "referee_stats_attributes"=>{"0"=>{"games_count"=>"4", "showcase_id"=>"1"}}}, "commit"=>"Create Game date"} User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]] GameDate Load (0.4ms) SELECT "game_dates".* FROM "game_dates" WHERE "game_dates"."date" IS NULL LIMIT 1 (0.2ms) BEGIN SQL (0.4ms) INSERT INTO "game_dates" ("date", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["date", "2016-04-01"], ["created_at", "2016-04-01 08:21:44.864669"], ["updated_at", "2016-04-01 08:21:44.864669"]] SQL (0.4ms) INSERT INTO "referee_stats" ("games_count", "showcase_id", "game_date_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["games_count", 4], ["showcase_id", 1], ["game_date_id", 7], ["created_at", "2016-04-01 08:21:44.866897"], ["updated_at", "2016-04-01 08:21:44.866897"]] (18.1ms) COMMIT Redirected to http://localhost:3000/showcases Completed 302 Found in 31ms (ActiveRecord: 20.1ms)

3

3 Answers

1
votes

It should be like :

def create
    @game_date = GameDate.find_or_create_by(game_date_params)
    if @game_date.present?
      redirect_to showcases_path
      flash[:success] = "Game date created"
    else
      render 'new'
    end
 end
1
votes

GameDate.find_or_create_by(game_date_params) would find record with ALL game_date_params, so you could do this by finding with specific params like date and assign rest of attributes to it via block. for example:

def create
  # find or initialize the record
  @game_date = GameDate.find_or_initalize_by(date: game_date_params[:date]) do |game_date|
    # Accept nested attributes as well
    game_date.assign_attributes(game_date_params)
  end

  if @game_date.save
    redirect_to showcases_path
    flash[:success] = "Game date created"
  else
    render 'new'
  end
end

See also: find_or_create_by and AttributesAssignment API docs

0
votes

Create action is for creating an object after the new action has been called and update action if the same but for edit. Mixing create & update logic i not a good idea. Maybe you should rethink what are you trying to do in your views.