Drawing routes with has keys complicates route drawing enough to warrant
deprecation. Transitioning the routing mapper to use keywords
would result in a 1.25-1.5x improvement in speed, and it would be
substantially easier to do if we drop this feature.
```ruby
get "/users" => "users#index"
post "/logout" => :sessions
mount MyApp => "/my_app"
get "/users", to: "users#index"
post "/logout", to: "sessions#logout"
mount MyApp, at: "/my_app"
```
Main motivation here was to fix the listings, they lacked markup.
Since I was on it, I edited the H1 Markdown headers, these are
not really used in individual CHANGELOG entries.
* lib/assets is too rare of a use case to warrant a default directory
Either these assets are part of your app, and should be in app/assets,
or you're getting them from a vendor, and they should be in
vendor/assets.
* Fix test
When config.i18n.raise_on_missing_translations = true, controllers and
views raise an error on missing translations. However, models won't.
This commit changes models to raise an error when
raise_on_missing_translations is true
Co-authored-by: Alex Ghiculescu <alex@tanda.co>
Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
A `raw_execute` implementation is now provided, instead adapters
have to implement `perform_query`.
It's a much simpler method that no longer need to concern itself
with Active Support notifications nor calling `with_raw_connection`.
The postgres adapter used to be more complex than the others to
be able to pass the prepared statement key to the `log` method.
If we instead add it to the payload later, we can simplify the method
further and it opens the door to refactor `log` and `with_raw_connection`
out of `raw_execute`.
Adapters have very inconsistent internal APIs to perform queries.
This refactoring tries to improve consistency with a common provite
API for all of them.
Abstract methods:
- `raw_execute`: the only method where an adapter should perform
a query. It returns a native, adapter specific result object.
Does not apply query transformations. Does not check for writes.
- `cast_result`: receives the native result object and returns
a generic `ActiveRecord::Result`.
- `affected_rows`: receives the native result object and returns
the number of affected rows.
By just implementing these 3 methods all adapters automatically get:
- `raw_exec_query`: same as `raw_execute` but returns an `ActiveRecord::Result`.
- `internal_exec_query`: same as `raw_exec_query` but check for writes and
apply query transformations.
- `internal_execute`: same as `internal_exec_query` but retuns the native,
adapter specific, result object.
With this increased conisistency, we can now reduce the ammount of
duplicated code in every adapter. There's some room for futher
improvments but I tried to not go too far all at once.
Also previously some adapters had a block based query interface that
allowed to eagerly clear the native result object.
It may make sense to bring that capability back in a consistent
way, but short term I opted for consistency.
Fix: https://github.com/rails/rails/issues/52429
The previous implementation assumed `NoMethodError` would be raised
when calling `super`, but that's not always true.
If the receiver is an implicit self, the raised error will be
`NameError`.
It's better not to rely on exceptions for this anyways.
Both "optional arguments" and "migrating processors" seem too specific
for where they were previously located within the section. Both ideas
are more complicated/processor specific, but are located very early on
when the ideas should be more simple/introductory.
This commit reorders the paragraphs a bit to improve the section's flow.
Now, the most basic examples are presented first, then the idea of
processors and what they have in common, and finally the more advanced
options and how the processors differ.
Provide instances with an opportunity to gracefully handle assigning to
an unknown attribute:
```ruby
class Rectangle
include ActiveModel::AttributeAssignment
attr_accessor :length, :width
def attribute_writer_missing(name, value)
Rails.logger.warn "Tried to assign to unknown attribute #{name}"
end
end
rectangle = Rectangle.new
rectangle.assign_attributes(height: 10) # => Logs "Tried to assign to unknown attribute 'height'"
```
By default, classes that do not override `#attribute_writer_missing`
will raise an `ActiveModel::UnknownAttributeError`.
The `attribute_writer_missing` aims to mimic the naming of
`BasicObject#method_missing`. There is also an
[ActiveModel::AttributeMethods#attribute_missing][] method, but that
pertains to attribute _access_.
[ActiveModel::AttributeMethods#attribute_missing]: https://edgeapi.rubyonrails.org/classes/ActiveModel/AttributeMethods.html#method-i-attribute_missing