Search code examples
ruby-on-railsscaffolding

Ruby on Rails/How to Scaffold form link to specific action?


My scaffold model doesn't work well with create action. I found out that if I press submit button, it is linked to TalksController#index but it should be linked to TalksController#create

I don't know how I can fix it to link to create action. There aren't any codes related to it in _form.html.erb and new.html.erb

Create worked well 2 days ago.

[edit]I post my codes. I added some codes in addition to the codes scaffold made itself

talks_controller.rb

  class TalksController < ApplicationController
  before_action :set_talk, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [ :index, :show, :all ]

  # GET /talks
  # GET /talks.json

  def all
    @talks = Talk.all
    @talks = Talk.order(created_at: :desc)
  end

  def index
    @talks = Talk.all
    @talks = Talk.order(created_at: :desc)

    @whichboard = params[:whichboard]
    @seq = params[:saveit]
    @title = params[:savetitle]
  end

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

  # GET /talks/new
  def new
    @talk = Talk.new
    @seq = params[:seq]
    @whichboard = params[:whichboard]
  end

  # GET /talks/1/edit
  def edit
    authorize_action_for @talk
  end

  # POST /talks
  # POST /talks.json
  def create
    @talk = Talk.new(talk_params)
    @talk.user_id = current_user
    @talk.seq = params[:talk][:seq]
    @talk.where = params[:talk][:where]

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

  end

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

  end


  # DELETE /talks/1
  # DELETE /talks/1.json
  def destroy
    authorize_action_for @talk
    @talk.destroy
    respond_to do |format|
      format.html { redirect_to talks_url, notice: 'Talk was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_talk
      @talk = Talk.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def talk_params
      params.require(:talk).permit(:content, :user_id, :seq, :where)
    end
end

_form.html.erb

<%= simple_form_for(@talk) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :content %>
    <%#= f.association :user %>
    <%= f.input :seq,  :as => :hidden, :input_html => { :value => @seq } %>
    <%= f.input :where,  :as => :hidden, :input_html => { :value => @whichboard } %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

new.html.erb

<div class="row">
  <div class='col-md-12'>
    <p style='text-align:right;'>
      created by <%= current_user.name %>, Current Time : <%= Time.now %>, board <%= @whichboard %> seq <%= @seq %>
    </p>
  </div>
</div>
<%= render 'form' %>
<%= link_to 'Back', talks_path %>

[SECOND EDIT] routes.rb

Rails.application.routes.draw do

  devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }

  root 'cpu#index'
  post ':controller(/:action(/:id(.:format)))'
  get ':controller(/:action(/:id(.:format)))'


  resources :talks
end

Solution

  • adjust your routes.rb

    Rails.application.routes.draw do
    
      devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
    
      root 'cpu#index'
    
    
      resources :talks
    
      #do you really need these? 
      post ':controller(/:action(/:id(.:format)))'
      get ':controller(/:action(/:id(.:format)))'
    
    
    
    end
    

    to put the resources :talks above the default/catchall routes. the routes are processed on first match, so if you need those default/catchalls youcan put them at the bottom. That being said, unless you have a requirement for them most modern rails apps don't require them by default, so you can probably comment out / remove them as another option.