rspec/rspec-rails

view spec: controller.extra_params cannot be used to set extra params for URL generation

mreinsch opened this issue · 2 comments

What Ruby, Rails and RSpec versions are you using?

Ruby version: ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [x86_64-darwin21]
Rails version: Rails 7.0.4.3
RSpec version: RSpec 3.12

  • rspec-core 3.12.2
  • rspec-expectations 3.12.3
  • rspec-mocks 3.12.5
  • rspec-rails 6.0.2
  • rspec-support 3.12.0

Observed behaviour

This is about a view spec. According to https://github.com/rspec/rspec-rails/blob/main/lib/rspec/rails/view_spec_methods.rb it should be possible to set extra params required for URL generation, but that isn't working (anymore?).

I'm doing something like:

before do
  controller.extra_params = { :seller_id => seller.id }
end

And in the template I'm using a URL method which requires a :seller_id in the path. This works fine serving the page, but in the view spec this causes a No route matches error with missing required keys: [:seller_id].

Expected behaviour

The extra_params should be used when URLs are generated.

Investigation / Suggested Fix

Rails is using a _recall hash in the options hash passed around for url generation to lookup previous path parameters. This is initialized in https://github.com/rails/rails/blob/58528bf270325789562413eec20b3cbf1a866e7f/actionpack/lib/action_controller/metal/url_for.rb#L33, using the request.path_parameters.

When I used the following code, the URL generation works fine:

before do
  request.path_parameters.merge!(seller_id: seller.id)
end

The extra_params on the other hand only seem to affect the request.path (maybe used in older Rails versions?). It should also adjust the request.path_parameters which should resolve the issue.

This is weird because we test this in features/view_specs/view_spec.feature, which method are you using that causes the error?

@JonRowe apologies for bumping an old thread but we've just ran into this today. We have a generic view used for multiple objects where we have the line
<%= link_to request.params.merge(sort_by: @name, sort_direction: link_sort_direction) do %>

we also ran into a url generation error where if we used

   request.path_parameters.merge!(x_id: x.id)

The param was set correctly, but

  controller.extra_params = { x_id: x.id }

Resulted in it being missing from request.params