macro_rules! joinable { ($($child:ident)::* -> $($parent:ident)::* ($source:ident)) => { ... }; }
Expand description
Allow two tables to be referenced in a join query without providing an
explicit ON
clause.
The generated ON
clause will always join to the primary key of the parent
table. This macro removes the need to call [.on
] explicitly, you will
still need to invoke
allow_tables_to_appear_in_same_query!
for these two tables to be able to use the resulting query, unless you are
using diesel print-schema
which will generate it for you.
If you are using diesel print-schema
, an invocation of this macro
will be generated for every foreign key in your database unless
one of the following is true:
- The foreign key references something other than the primary key
- The foreign key is composite
- There is more than one foreign key connecting two tables
- The foreign key is self-referential
ยงExample
use schema::*;
joinable!(posts -> users (user_id));
allow_tables_to_appear_in_same_query!(posts, users);
let implicit_on_clause = users::table.inner_join(posts::table);
let implicit_on_clause_sql = diesel::debug_query::<DB, _>(&implicit_on_clause).to_string();
let explicit_on_clause = users::table
.inner_join(posts::table.on(posts::user_id.eq(users::id)));
let explicit_on_clause_sql = diesel::debug_query::<DB, _>(&explicit_on_clause).to_string();
assert_eq!(implicit_on_clause_sql, explicit_on_clause_sql);
In the example above, the line joinable!(posts -> users (user_id));
specifies the relation of the tables and the ON clause in the following way:
child_table -> parent_table (foreign_key)
-
parent_table
is the Table with the Primary key. -
child_table
is the Table with the Foreign key.
So given the Table declaration from Associations docs
- The parent table would be
User
- The child table would be
Post
- and the Foreign key would be
Post.user_id
For joins that do not explicitly use on clauses via JoinOnDsl
the following on clause is generated implicitly:
post JOIN users ON posts.user_id = users.id