fablabbcn / smartcitizen-api

The Smart Citizen Engine
https://developer.smartcitizen.me
GNU Affero General Public License v3.0
10 stars 4 forks source link

Multiple ransak filters in URL - `with_tags` ransak filter missing on documentation #186

Open pral2a opened 3 years ago

pral2a commented 3 years ago

Ransack for (single) tag (association) names works out of the box:

How do we use multiple tags in URL? :thinking:

https://github.com/fablabbcn/smartcitizen-api/blob/4706778e5a657acfb689ad262c179f972c98a660/app/controllers/v0/devices_controller.rb#L16-L20

I think it's missing in API docs here

https://developer.smartcitizen.me/#basic-searching

viktorsmari commented 3 years ago

https://github.com/fablabbcn/smartcitizen-api/blob/4706778e5a657acfb689ad262c179f972c98a660/app/models/device.rb#L99-L101

I added the documentation - but was it supposed to handle 2 (multiple) tags using the pipe (|) ? That did not work when I tried it. Needs some work / changes if that is the desired behaviour

If the plan is to find either 'Barcelona' OR 'Amsterdam', we can replace find_by with where: Tag.where(name: ['Barcelona','Amsterdam'])

When using multiple tags (|) - it looks like it always finds the Tag with the lowest id number (the oldest id in the database) Tag.find_by!(name: ['Barcelona','Amsterdam']) : Finds Amsterdam Tag.find_by!(name: ['Amsterdam','Barcelona']) : Finds Amsterdam Tag.find_by!(name: 'Barcelona|Amsterdam|Manchester'.split('|')) Finds Amsterdam

pral2a commented 3 years ago

Thanks or the assessment. I will suggest you work whenever you have time to support multiple tags filtering using the OR operation as described.

viktorsmari commented 3 years ago

Temporarily(?) added support multiple for OR tags using our custom param with_tags http://localhost:3000/devices?with_tags=Barcelona|Manchester

This is not using Ransack q params, instead we inject it manually. Preferably we should use Ransack for everything (if possible). Then we can simplify the code and remove the if params[:with_tags] check.

Thoughts:

Ransack for multiple tag names works in this Console command: Device.ransack('tags_name_in': ['Amsterdam', 'Barcelona']).result.count

Result of a single tag name URL: Parameters: {"q"=>{"tags_name_in"=>"Manchester"}}

timcowlishaw commented 1 week ago

Four years later, after stumbling across this in a comment in the codebase :-)

This is entirely possible! You just repeat the param you're interested in, and suffix it with square brackets, like:

http://localhost:3000/devices?q[tags_name_in][]=Barcelona&q[tags_name_in][]=Amsterdam".

Given I'm working on a new API version, I might leave the "with_tags" hack out in V1, as updating to use this style of querying would be a breaking change.

(unless we feel that with_tags is more user-friendly and we want to keep it: the "rails way" described above is kinda ugly, and not necessarily intuitive if you don't already know about it, as this issue suggests)