Reputation: 1931
I have the following route:
get 'calendar(/:month(/:year))' => 'calendar#show', as: :calendar,
constraints: { month: /[a-z]+/, year: /\d{4}/ },
defaults: { month: Date::MONTHNAMES[Date.today.month].downcase, year: Date.today.year }
Using this route in the console I get:
app.calendar_path(month: 'september', year: '2017')
=> "/calendar"
Which is OK, since it realizes these parameters are the defaults when I'm writing this so it removes them from the generated path.
But I don't understand why:
app.calendar_path(month: 'september', year: '2018')
=> "/calendar"
2018 is the next year, so I would expect the path to be "/calendar/september/2018". The behaviour is the same for 2019, and for any year with the month being the current one.
Edit: Only reproduces in Rails 4.2.6, Rails 4.2.8 - Seems to be fixed in Rails 5+
Upvotes: 2
Views: 49
Reputation: 2242
It looks like it is the combination of having optional parts in the path and having defaults. At least from a rendering perspective, that combination does make no sense wenn you think about it. I haven't checked dispatching where I can see why you would want to have the optional parts but you might get away with specifying a separate route for that purpose:
get 'calendar/:month/:year' => 'calendar#show',
as: :calendar,
constraints: { month: /[a-z]+/, year: /\d{4}/ },
defaults: { month: Date::MONTHNAMES[Date.today.month].downcase,
year: Date.today.year }
# :year can be omitted here as the route before would have caught that
get 'calendar(/:month)' => 'calendar#show',
as: :calendar_fallback,
constraints: { month: /[a-z]+/ }
Upvotes: 1