Ask A Question

Notifications

You’re not receiving notifications from this thread.

Ransack Scoping issues

alexander kehaya asked in General

Hey everyone, Just posted this question to stack overflow but thought I'd give it a try hear. I've been trying to figure out how to scope ransack searching for a couple of weeks but haven't figured it out. Here's the link to my question. http://stackoverflow.com/questions/30578520/limiting-search-results-to-associated-model-with-ransack-gem

Any thoughts?

Reply

It looks like the main thing is that you need to set @school in the action. Once you have that, you can either merge that into the params[:q] search options or add where(school: @school) into your query.

Can you access the school off the URL or the current user?

Reply

Thanks for the response. I added this to the pins controller:

def index
@school = School.find(params[:id])
@q = Pin.search(params[:q]).where(school: @school)
@pins = @q.result(distinct: true).order("created_at DESC").paginate(:page => params[:page], :per_page => 10 )
respond_with(@pins)
authorize @pins
end

When I search for a student name I get this error. "Couldn't find School without an ID"

In the url on the school's home page i have /schools/1. 1 is the id but when it goes to pin/index it looses the school id. Do I need to get re configure this to all happen in the school controller?

Reply

What's the URL for the Pins index? Is it /schools/:school_id/pins?

Reply

/pins?utf8=%E2%9C%93&q%5Buser_name_cont%5D=kid

That's where it takes me after I search fro /school/1

Reply

Maybe I should put the search inside of the school show method?

Reply

It might make sense to have pins nested under the school depending on what you're trying to accomplish. If you're trying to scope the pins to a school, that's what I would do. Then you can grab the school's ID from the url to filter the search.

The other alternative is to put a hidden field in the form to pass in the school_id_eq parameter in the URL so that pins are filtered by that ID. This makes the pins controller generic, so it can be used for seeing pins from multiple schools.

Reply

I'm just trying to allow an admin user to search for a list of pins created by a user from their school by the user's name. I don't want them to be able to find pins of other users as it's sensitive data. It seems like your first idea would be better but I'm not entirely sure. How would I grab the id from the url ? In the routes file?

Reply

Gotcha, yeah you would definitely want to separate those then.

So here's how you can set that up (basically nested routes).

resources :schools do
  resources :pins, module: :schools
end

This route basically generates /schools/:school_id/pins (verify that with rake routes).

That means you can query the school from the URL by doing @school = School.find(params[:school_id])

# app/controllers/schools/pins_controller.rb
class Schools::PinsController
  def index
    @school = School.find(params[:school_id])
    @q = Pin.search(params[:q])
    @pins = @q.result(distinct: true).where(school: @school).order("created_at DESC").paginate(:page => params[:page], :per_page => 10 )
    respond_with(@pins)
    authorize @pins
  end
end

I moved the where into the result line because that's where you're doing the other scopes so it fits a bit better. In general, I think that should work and should separate out things nicely between the schools.

You can also authorize @school here to verify they can only ever see pins for their school as an added bonus.

Reply

Thanks! This is really cool. I appreciate the help. Testing it now.
I'll let you know if it works.

Reply

So I added all of the above. But I don't have a schools folder in my controller folder.
app/controllers/pins_controller.rb is where I put the code. When I run the search I get this error.

Routing Error
uninitialized constant PinsController::Schools

That's pretty clear where the error is. I tried creating a schools file and a second pins_controller.rb file with just the code in that but it didn't work. Instead of an error it just keeps redirecting to school/school_id

Edit: I did check the routes and they are working correctly /schools/:school_id/pins

Reply

Can you post your routes.rb file and the output rake routes ?

Reply

So I added my routes.rb and rake routes output here. http://stackoverflow.com/questions/30578520/limiting-search-results-to-associated-model-with-ransack-gem

Rake routes is a bit tough because it's so long but I thought I'd just add the routes for pins and schools. Is that enough?

Reply

Yep! Routes are fine.

You want to put the code in the app/controllers/schools folder so that it can detect it properly as the module. Just create it and store it in there and you'll be fine.

Also you want to have it inherit from ApplicationController because I forgot that part.

Might give this episode on nested routes a rewatch. This is where I touched on how the modules/nesting work for organizing your code into folders.

Reply

Thanks this is super helpful! I think I understand now from watching the video. I'll need to move my schools_controller.rb file and my pins controller.rb file into the app/controllers/schools folder. I'll also need to move my pins views folder into the view/schools folder. Is that right? I'll give it a shot today and let you know if it works.

Thanks again! really learning a ton.

Reply

That's all correct except I don't think you need to move the schools_controller.rb because it's a top level controller.

Good luck and fingers crossed it all works! :)

Reply

I got a no method error for pins_path in schools#show. So I changed the global search variable that's set in my application controller From

def set_global_search_variable
@q = Pin.search(params[:q])
end

To:

def set_global_search_variable
@q = School.search(params[:q])
end

the error goes away. When I search I now get a new error.
No route matches [GET] "/schools"

I don't think the answer is to change Pin to School. I tried School.pins.search but that's a no method error for pins in school#show. Added @pins =Pin.all to the show method and that's also not working. Started running around in circles with this so asking for a little more help. I think I'm close. Really appreciate your help

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 85,376+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.