activerecord-hackery / ransack

Object-based searching.
https://activerecord-hackery.github.io/ransack/
MIT License
5.69k stars 807 forks source link

Rails 7.2.1, Ransack 4.2.1 ransack is not working. #1519

Open orkhan opened 3 months ago

orkhan commented 3 months ago

Ransack is not working, it's not returning filtered results. Just all results

Started GET "/api/v1/stations?q[station_plug_types_plug_type_id_eq]=bfce2465-c064-423b-bb72-7cc7af2039f7&q[max_kwh_eq]=0" for ::1 at 2024-08-29 17:24:35 +0400 Processing by Api::V1::StationsController#index as JSON Parameters: {"q"=>{"station_plug_types_plug_type_id_eq"=>"bfce2465-c064-423b-bb72-7cc7af2039f7", "max_kwh_eq"=>"0"}} Unpermitted parameter: :format. Context: { controller: Api::V1::StationsController, action: index, request: #<ActionDispatch::Request:0x0000000127494d00>, params: {"q"=>{"station_plug_types_plug_type_id_eq"=>"bfce2465-c064-423b-bb72-7cc7af2039f7", "max_kwh_eq"=>"0"}, "format"=>:json, "controller"=>"api/v1/stations", "action"=>"index"} } Ransack::Search<class: Station, base: Grouping <conditions: [Condition <predicate: eq, values: ["bfce2465-c064-423b-bb72-7cc7af2039f7"]>, Condition <predicate: eq, values: [0]>], combinator: and>> Station Load (0.6ms) SELECT DISTINCT "stations".* FROM "stations" LEFT OUTER JOIN "station_plug_types" ON "station_plug_types"."station_id" = "stations"."id" ↳ app/controllers/api/v1/stations_controller.rb:7:inindex' Provider Load (0.3ms) SELECT "providers". FROM "providers" WHERE "providers"."id" = $1 [["id", "9a2f9e1b-87df-4538-aaf8-16efe51055ee"]] ↳ app/controllers/api/v1/stations_controller.rb:7:in `index' HABTM_Amenities Load (0.2ms) SELECT "amenities_stations". FROM "amenities_stations" WHERE "amenities_stations"."station_id" = $1 [["station_id", "34286d84-8c3f-4bf6-9d7a-bb03845ec0c6"]] ↳ app/controllers/api/v1/stations_controller.rb:7:in index' Amenity Load (0.3ms) SELECT "amenities".* FROM "amenities" WHERE "amenities"."id" = $1 [["id", "9b57b6b2-c45a-4706-b474-6079d657f6fe"]] ↳ app/controllers/api/v1/stations_controller.rb:7:inindex' City Load (0.2ms) SELECT "cities". FROM "cities" WHERE "cities"."id" = $1 [["id", 1]] ↳ app/controllers/api/v1/stations_controller.rb:7:in `index' StationPlugType Load (0.2ms) SELECT "station_plug_types". FROM "station_plug_types" WHERE "station_plug_types"."station_id" = $1 [["station_id", "34286d84-8c3f-4bf6-9d7a-bb03845ec0c6"]] ↳ app/controllers/api/v1/stations_controller.rb:7:in index' State Load (0.2ms) SELECT "states".* FROM "states" WHERE "states"."id" = $1 [["id", 1]] ↳ app/controllers/api/v1/stations_controller.rb:7:inindex' PlugType Load (0.3ms) SELECT "plug_types". FROM "plug_types" WHERE "plug_types"."id" = $1 [["id", "bfce2465-c064-423b-bb72-7cc7af2039f7"]] ↳ app/controllers/api/v1/stations_controller.rb:7:in `index' Country Load (0.3ms) SELECT "countries". FROM "countries" WHERE "countries"."id" = $1 [["id", 1]] ↳ app/controllers/api/v1/stations_controller.rb:7:in index' [active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Attributes (1.72ms) Completed 200 OK in 21ms (Views: 17.2ms | ActiveRecord: 2.5ms (9 queries, 0 cached) | GC: 4.9ms)

es-ki commented 3 months ago

same

scarroll32 commented 2 months ago

Possible cause https://github.com/activerecord-hackery/ransack/blob/main/lib/polyamorous/polyamorous.rb#L19C1-L20C1

dmytro-strukov commented 1 month ago

Maybe it will help someone who is also debugging this issue.

Rails 7.2.1 Ruby 3.2.2

x = ArticleCategory.ransack(title_eq: 'Child category')
x.result

It produces the next SELECT "article_categories".* FROM "article_categories" /* loading for pp */ LIMIT $1 [["LIMIT", 11]]

It returns all of the records (should not).

Backtrace of the calls:

ransack-4.2.1/lib/ransack/adapters/active_record/base.rb:15

def ransack(params = {}, options = {})
  Search.new(self, params, options)
end

ransack-4.2.1/lib/ransack/search.rb:43

def result(opts = {})
  @context.evaluate(self, opts)
end

ransack-4.2.1/lib/ransack/adapters/active_record/context.rb:27

def evaluate(search, opts = {})
  viz = Visitor.new
  relation = @object.where(viz.accept(search.base))
   ...
end

ransack-4.2.1/lib/ransack/visitor.rb viz.accept will call visit method here:

def visit(object)
  send(DISPATCH[object.class], object)
end

and this will call visit_Ransack_Nodes_Condition and visit_Ransack_Nodes_Grouping.

The strange behavior that I noticed is that Ransack::Nodes::Condition does not have attributes, it returns an empty array. I read test cases so probably it is not correct behavior, also I run tests locally and they are all green, so the current issue is not covered by them.

AlexisKAndersen commented 1 month ago

I am also experiencing this issue. Is there any progress on addressing it?

AlexisKAndersen commented 1 month ago

I am also experiencing this issue. Is there any progress on addressing it?

In my case, it seems that my ransackable_attributes were defined as a symbol array (%i[]) and changing it to a word array (%w[]) fixed it. It does, however, seem like a bad thing that the symbol array is recognized sufficiently to make ransack believe the method names are accounted for, but not enough to actually use them.