As the API doc shows, `references` should be given table names.
https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-references
However, people (and test cases in the our codebase) sometimes give
association names for `references`.
Since the API example and all test cases in the codebase use symbols as
arguments, so I regarded symbols as user given values in #40106.
But as #40743 indicates, people also use string association names, it
would have unexpected side-effect especially if singular association
names given.
As much as possible to avoid to use user given values, mark internal
references for `where` and use only them for join aliases.
Fixes#40743.
We don't need a callback and we should not expose the attribute to the
API given this is only internal.
I also removed the CHANGELOG entry because this is a bugfix for a change
that was not released yet.
This commit allows passing a custom `purpose:` keyword argument to both
`find_signed!` and `signed_id`. This matches the signature of the
`super` methods in ActiveRecord, and it is already possible with the
non-bang [`find_signed`][find_signed] method, since that one doesn't
have an override in ActiveStorage (although perhaps it should, to set
the default :blob_id purpose)
This is useful in cases where you want to further isolate different
types of blobs, for example if they have different levels of
authorization.
[find_signed]: be11d1b6e8/activerecord/lib/active_record/signed_id.rb (L42-L48)
When we use `bin/yarn` without original yarn,
the following error will be occurred:
```
bin/yarn:12:in `initialize': no implicit conversion of nil into String (TypeError)
```
This means `executable_path` is `nil`.
To handle missing yarn correctly, checking `executable_path` seems good.
This is a result of my local without yarn.
```
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
rake aborted!
```
This commit follows up https://github.com/rails/rails/pull/40646.
Before this change while inspect was respecting that option, attribute_for_inspect
was not.
I also changed inspect to use attribute_for_inspect so we make sure the behavior
is consistent in the two places and simplified the implementation.
Fixes#40725.
This links the first mention of each method to its API documentation,
similar to a Wikipedia article.
This also modifies the text in a few places to ensure that methods are
explicitly mentioned and linked.
`form_with` would generate a remote form by default.
This confused users because they were forced to handle remote requests.
All new 6.1 applications will generate non-remote forms by default.
When upgrading a 6.0 application you can enable remote forms by default by
setting `config.action_view.form_with_generates_remote_forms` to `true`.
This change allows for applications to optionally run a `default_scope`
on `update` and `delete` queries. Default scopes already ran on select
and insert queries.
Applications can now run a set default scope on all queries for a model
by setting a `all_queries` option:
```ruby
class Article < ApplicationRecord
default_scope -> { where(blog_id: 1) }, all_queries: true
end
```
Using the default scope in this way is useful for applications that need
to query by more than the primary key by default. An example of this
would be in an application using a sharding strategy like Vitess like.
For Rails sharding, we route connections first and then query the
database. However, Vitess and other solutions use a parameter in the
query to figure out how to route the queries. By extending
`default_scope` to apply to all queries we can allow applications to
optionally apply additional constraints to all queries. Note that this
only works with `where` queries as it does not make sense to select a
record by primary key with an order. With this change we're allowing
apps to select with a primary key and an additional key.
To make this change dynamic for routing queries in a tenant sharding
strategy applications can use the `Current` API or parameters in a
request to route queries:
```ruby
class Article < ApplicationRecord
default_scope -> { where(blog_id: Current.blog.id) }, all_queries: true
end
```
In order to achieve this I created a new object when default scopes are
created. This allows us to store both the scope itself and whether we
should run this on all queries. I chose not to implement an `on:` option
that takes an array of actions because there is no simple or clear way
to turn off the default scope for create/select. It also doesn't really
make sense to only have a default scope for delete queries. The decision
to use `all_queries` here allows for the implementation to be more
flexible than it was without creating a mess in an application.
`ActionView::Helpers::FormBuilder#id`
---
Generate an HTML `id` attribute value.
Return the [`<form>` element's][mdn-form] `id` attribute.
```html+erb
<%= form_for @post do |f| %>
<%# ... %>
<% content_for :sticky_footer do %>
<%= form.button(form: f.id) %>
<% end %>
<% end %>
```
In the example above, the `:sticky_footer` content area will exist
outside of the `<form>` element. [By declaring the `form` HTML
attribute][mdn-button-attr-form], we hint to the browser that the
generated `<button>` element should be treated as the `<form>` element's
submit button, regardless of where it exists in the DOM.
[A similar pattern could be used for `<input>`
elements][mdn-input-attr-form] (or other form controls) that do not
descend from the `<form>` element.
`ActionView::Helpers::FormBuilder#field_id`
---
Generate an HTML <tt>id</tt> attribute value for the given field
Return the value generated by the <tt>FormBuilder</tt> for the given
attribute name.
```html+erb
<%= form_for @post do |f| %>
<%= f.label :title %>
<%= f.text_field :title, aria: { describedby: form.field_id(:title, :error) } %>
<span id="<%= f.field_id(:title, :error) %>">is blank</span>
<% end %>
```
In the example above, the <tt><input type="text"></tt> element built by
the call to <tt>FormBuilder#text_field</tt> declares an
<tt>aria-describedby</tt> attribute referencing the <tt><span></tt>
element, sharing a common <tt>id</tt> root (<tt>post_title</tt>, in this
case).
This method is powered by the `field_id` helper declared in
`action_view/helpers/form_tag_helper`, which is made available for
general template calls, separate from a `FormBuilder` instance.
[mdn-form]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form
[mdn-button-attr-form]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-form
[mdn-input-attr-form]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-form
[mdn-aria-describedby]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-describedby_attribute
[w3c-wai]: https://www.w3.org/WAI/tutorials/forms/notifications/#listing-errors
Follow-up to 75c309c7ad6517a7fad482f1efd50baadf4bdf45.
As a result of these changes, attributes can have their type and default
value configured separately. Similar behavior was implemented in #39380,
but only for attributes that derive (and do not override) their type
from the database.