2

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: &#39;3&#39; _: &#39;1498731378829&#39; ===> **I don't know what is this controller: cases action: show ===> obvious the action is on case#show student_id: &#39;1&#39; 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!!!

3 Answers 3

1

The route get 'update_subjects', to: 'cases#update_subjects' is conflicting with the below restful route

/students/:student_id/cases/:id/ case#show

So it is routing to the wrong method(it should route to update_subjects instead)

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"}

which is the reason to your problem.

Solution:

Correct your routes!

resources :students do
 resources :cases
end
get '/update_subjects', to: 'cases#update_subjects'

and use '/update_subjects' instead of 'update_subjects' in the AJAX call

Sign up to request clarification or add additional context in comments.

2 Comments

omg! u are my saviour!! haha, I know there is something to do with it, but I just couldn't figure this out. Can I read it as the ajax path like this situation can be independent of those resources stuff? Trying to learn all these routing stuff and ajax and respond_to/wtih
@StargazerYip I always recommend the Guides. Check resource-routing-the-rails-default and working_with_javascript_in_rails
0

I think your problem is related to the route, you should be using on the ajax call:

/students/:student_id/cases/:case_id/update_subjects?...

And not:

/students/1/cases/update_subjects?...

You can execute on the terminal:

rake routes

And this outputs all available routes.

Comments

0

your route in ajax call is incorrect.

corrected code:

$.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!")

1 Comment

thx for your information!!... should have avoid the the reserved word... trying to get it a new name haha..THX!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.