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