Question: Rails Ajax - View Filtering by joined record

Question

Rails Ajax - View Filtering by joined record

Answers 3
Added at 2017-01-02 19:01
Tags
Question

I'm trying to allow an end user to filter a data grid by an associated record. The data grid is showing a list of Activities:

Model for activity.rb (the list of records)

class Activity < ApplicationRecord
    belongs_to :student
    belongs_to :user
end

Model for student.rb (what I'm trying to filter on)

class Student < ApplicationRecord
    belongs_to :user
    has_many :activities
    validates_attachment_content_type :image, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"], :convert_options => "-auto-orient"
    validates :firstname, :presence => true

end

Here's the view in index.html.erb:

<heading>

    <h1 class="activity">Activity</h1> 

    <div class="filter">
        <%= collection_select :students, :ids, Student.where(user_id: current_user), :id, :firstname, {}, {:onchange => '$.get("/filter_students")'} %>
    </div>

    <div class="left">
        <div class="timeblock">
            <div class="label">Date</div>
            <div class="value"><%= activity.created_at.strftime("%b %e") %></div>
        </div>
        <div class="student-name"><%= activity.student.try{|s| s.firstname} || "Deleted Student" %></div>
        <%= activity.name %>
    </div>

...

and my activities_controller.rb

def index
    @activities = Activity.where(user_id: current_user).order('created_at DESC').limit(50)
end
def filter_students
    @activities = Activity.find(params[:id])
    respond_to do |format|
      format.js { render 'student_activites', :formats => [:js] }
    end
end

I'm getting the select with the students first names back, but when I click it, here's the js error I'm getting:

GET http://localhost:3000/filter_students 404 (Not Found)

Edit Here's the routes:

Rails.application.routes.draw do
  resources :activities
  resources :students
end
Answers
nr: #1 dodano: 2017-01-02 20:01

The URL the app is retrieving is: http://localhost:3000/filter_students. You need to change to something like this: http://localhost:3000/activities/filter_students, to specify the controller of your action. Just add the controller to your onchange directive on the collection_select.
You also need to tell Rails that you have a route filter_students inside your ActivitiesController that is applied to a collection, e.g the filter student is not applied to a specific activity, so you need to put in your routes.rb:

resources :activities do
  collection do
    get :filter_students
  end
end
resources :students
nr: #2 dodano: 2017-01-02 20:01

You need to add the filter_students route:

get 'filter_students', to: 'activities#filter_student'
nr: #3 dodano: 2017-01-02 22:01

Based on the current construction of your filter_students method in your activities_controller I would do this:

routes.rb

# filter_students is trying to find @activities based on params[:id]
## so you need to send params[:id] via the member do block of the activites resource below
resources :activities do
  # member rather than collection
  # member will allow you to pass params[:id] like you have in you controller
  member do
    get :filter_students
  end
end
resources :students

Then use activity.id (it looks like you are already using activity in your index view) to the activity id to the url

index.html.erb - edited 1/3/17

<%# your onchange url needs to look like this /activity/:id/filter_students %>
<%# ... to work with the routes you setup above and the logic in your controller %>
<%= collection_select :students, :ids, Student.where(user_id: current_user), :id, :firstname, {}, {:onchange => '$.get("/activity/<%= activity.id %>/filter_students")'} %>
Source Show
◀ Wstecz