Ad

Can't Create New Database Entry From Form Submission

I have User and Pairings models as such:

class User < ActiveRecord::Base

  enum role: [:student, :supervisor, :admin]
has_many :students, class_name: "User",
                      foreign_key: "supervisor_id"

  belongs_to :supervisor, class_name: "User"

  has_and_belongs_to_many :pairings
end

class Pairing < ActiveRecord::Base

  has_and_belongs_to_many :supervisor, class_name: 'User'
  belongs_to :student, class_name: 'User'

end

And the related parts from schema (removed devise fields for size):

ActiveRecord::Schema.define(version: 20160221222318) do
create_table "pairings", force: :cascade do |t|
    t.integer  "supervisor_id"
    t.integer  "student_id"
    t.string   "project_title"
  end

  add_index "pairings", ["student_id"], name: "index_pairings_on_student_id", unique: true
  add_index "pairings", ["supervisor_id"], name: "index_pairings_on_supervisor_id"

  create_table "users", force: :cascade do |t|
    t.string   "name"
    t.integer  "role"
    t.integer  "supervisor_id"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true

end

I have a view with a form which holds 1 dropdown box listing all students and 1 listing all supervisors. My goal is twofold:

(1) once a supervisor and student are selected from the boxes, get their ids and asssign the id of the supervisor to the supervisor_id column of the student. (Done using AJAX Patch request)

(2) crate a new row in the pairings table with the ids from the dropdowns. (Done through the pairings_controllers create method)

This is my view:

<script>

$("#my_special_form").submit(function(){
  var url = "/users/" + this.elements["pairing[student_id]"].value;

  $.ajax(url, {
    beforeSend: $.rails.CSRFProtection,
    data: {
      user: {
        supervisor_id: this.elements["pairing[supervisor_id]"].value
      }
    },
    type: 'PATCH',
    dataType: 'JSON',
    success: function(data, textStatus, jqXHR) {
      console.log('Success', data, textStatus, jqXHR);
    },
  });

  return false; // cancels out the normal form submission
});

</script>


<%= form_for(Pairing.new, url: pairings_path, method: :post, html: { id: 'my_special_form' }) do |f| %>
  <div class="field">
    <%= f.label :supervisor_id %>
    <%= f.collection_select(:supervisor_id, User.where(role: 1), :id, :name) %>
  </div>
  <div class="field">
    <%= f.label :student_id %>
    <%= f.collection_select(:student_id, User.where(role: 0), :id, :name) %>
  </div>
  <div class ="field">
    <%= f.label :project_title %>
    <%= f.text_field :project_title %>
  <%= f.submit %>
<% end %>

And the controllers:

class PairingsController < ApplicationController
    def new
        @pairing = Pairing.new
    end

  def create
    @pairing = Pairing.new(pair_params)
  end

  def update
    @pairing = Pairing.find(params[:id])
    @pairing.update_attributes(pairing_params)
  end

  private
    def pair_params
      params.require(:pairing).permit(:supervisor_id, :student_id, :project_title)
    end
end

class UsersController < ApplicationController
  before_action :authenticate_user!
  after_action :verify_authorized

  def index
    @users = User.all
    authorize User
  end

  def show
    @user = User.find(params[:id])
    authorize @user
  end

  def update
    @user = User.find(params[:id])
    authorize @user
    if @user.update_attributes(secure_params)
      redirect_to users_path, :notice => "User updated."
    else
      redirect_to users_path, :alert => "Unable to update user."
    end
  end

  private

  def secure_params
    params.require(:user).permit(:role, :supervisor_id)
  end

end

The problem I'm having is that the script doesn't succeed but still manages to update the supervisor_id field. I tried testing without the script to see if the pairing table entry would get created and it still hasn't as the parameters from the forms are received but aren't committed to the transaction once the button is pressed. Don't know what to do really any help is appreciated !

Ad

Answer

Solved by doing the following changes

<%= form_for(Pairing.new, url: new_pairing_path, method: :post, html: { id: 'pairing_form' }) do |f| %>

Routes.rb

match '/pairings/new', to: 'pairings#create', via: [:post]
match '/users/update', to: 'users#update', via: [:patch]
Ad
source: stackoverflow.com
Ad