I have struggled with this problem for a few days, every time when I thought I get the trick, I missed it, so I am asking for your help! So I have been working on a private tutor centre project where I need to have a dynamic selection box which has values based on a previous selection box. I have followed the tutorial: https://kernelgarden.wordpress.com/2014/02/26/dynamic-select-boxes-in-rails-4/
For my work:
Models
student.rb
class Student < ApplicationRecord
has_many :cases
end
case.rb
class Case < ApplicationRecord
belongs_to :category
belongs_to :student
belongs_to :subject
end
category.rb
class Category < ApplicationRecord
has_many :cases
has_many :subjects
end
subject.rb
class Subject < ApplicationRecord
belongs_to :category
has_many :cases
end
Routes
routes.rb
resources :students do
resources :cases do
get 'update_subjects', to: 'cases#update_subjects'
end
end
Controller
cases_controller.rb
class CasesController < ApplicationController
before_action :set_student, only: [:new]
def index
end
def show
end
def new
@case = @student.cases.build
@categories = Category.all
@subjects = Subject.where("category_id = ?", Category.first.id)
end
def update_subjects
@subjects = Subject.where("category_id = ?", params[:category_id])
respond_to do |format|
format.js
end
end
private
def case_params....
View
views/cases/_form.html.erb
<%= form_for [@student, @case] do |f| %>
.....
<%= f.select :category_id, options_for_select(@categories.collect { |category| [category.category_name.titleize, category.id]}, 1), {},{ id: 'categories_select' } %>
<%= f.label 'Please select the category' %>
<%= f.select :subject_id, options_for_select(@subjects.collect { |subject|[subject.subject_name.titleize, subject.id]}, 0), {},{ id: 'subjects_select' } %>
<%= f.label 'Please select the subject' %>
....
views/cases/update_subjects.js.erb
$("#subjects_select").empty().append("<%=j render(@subjects) %>")
views/subjects/_subject.html.erb
<option value="<%= subject.id %>"><%= subject.subject_name.titleize %></option>
AJAX
assets/javascripts/cases.js.coffee
$ ->
$(document).on 'change', '#categories_select', (evt) ->
$.ajax 'update_subjects',
type: 'GET'
dataType: 'script'
data: {
category_id: $("#categories_select").val()
}
error: (jqXHR, textStatus, errorThrown) ->
console.log("AJAX Error: #{textStatus}")
success: (data, textStatus, jqXHR) ->
console.log("Dynamic country select OK!")
assets/javascripts/application.js
//= require rails-ujs
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
Rails details
Ruby version = 2.4.1 Rails version = 5.1.1
Main problem
The ajax did work, but it return AJAX Error: parsererror and without any controller errors. So, I search out about pasererror, and I know the dataType expect a javascript format in return so I checkout my developer tool on safari. From the tool, I can see that there is an XHRs folder whenever I select a option in the category field. and inside that folder I can see a file containing a html file and the most interesting thing is that I think the update_subjects method is not working since inside the file, it shows(As I have used debugger inside my code):
<pre class="debug_dump">--- !ruby/object:ActionController::Parameters
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
category_id: '3' _: '1498731378829' ===> **I don't know what is this
controller: cases action: show ===> obvious the action is on case#show student_id: '1'
id: update_subjects permitted: false </pre>
and in the terminal:
Started GET
"/students/1/cases/update_subjects?category_id=3&_=1498731378829"
Processing by CasesController#show as JS
Parameters: {"category_id"=>"3", "_"=>"1498731378829", "student_id"=>"1", "id"=>"update_subjects"}
Rendering cases/show.html.erb within layouts/application
Rendered cases/show.html.erb within layouts/application (0.6ms)
Student Load (0.4ms) SELECT "students".* FROM "students" WHERE "students"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Rendered students/_nav_after_login.html.erb (0.8ms) [cache miss]
Completed 200 OK
Sorry for such a long paragraph, since I want to provide you as much as I can to figure this out. I think the main difference between my work and the tutorial is my CASE is based on STUDENT and I don't figure out the routes or something... or maybe I have got typos???? Thanks for your help in advance!!!