joinable

Macro joinable 

Source
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