Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is far from complete, but I wanted to create a WIP right away to explain it since it's a big change with some benefits for anyone using Mobility with querying.
The change is to migrate the querying support offered by Mobility into a shared plugin. Rather than each backend independently overriding methods like
where
, the plugin does this overriding in one place and calls two methods on the backend class, which each backend can customize.These methods are
build_node
andadd_scope
(exact names may change). Each backend only needs to implement these methods to support querying.build_node
takes an attribute name, a locale (currentlyMobility.locale
) and a set of backend options and returns an Arel node.add_scope
takes a relation, a hash of attributes and values, and a hash of backend options and returns an (optionally) modified relation.Why is this important? Because it means that we can fully abstract how backends handle querying into these two methods. e.g. for the Table backend (for which I've got specs now passing),
build_node
creates a node for the column on the translation table, whereasadd_scope
joins the translation table to the model table on the relation.For the jsonb backend, the node would be e.g.
post.title -> 'en'
, for an English locale, etc.This is really powerful because it means that we can now do more complex querying. e.g. suppose you want to case-sensitively search for a translated value independent of backend. With this change, if you get the node with
build_node
, you can then build a predicate withnode.lower.eq("foo")
. Previously, there was no backend-independent way of doing this.This means that e.g. the uniqueness validator could support case-insensitivity, fixing #141. But it also means it would be possible to build extension gems to support integration with e.g. Ransack, etc. in a backend-independent way.
The code here is quite complex but when this is all done, things should be simpler since all the backend-specific
QueryMethods
classes will be removed, so complexity will be captured exclusively by one (plugin) class.