Skip to main content

diesel/associations/
mod.rs

1//! Traits related to relationships between multiple tables.
2//!
3//! Associations in Diesel are always child-to-parent.
4//! You can declare an association between two records with `#[diesel(belongs_to)]`.
5//! Unlike other ORMs, Diesel has no concept of `has many`
6//!
7//! ```rust
8//! # include!("../doctest_setup.rs");
9//! use schema::{posts, users};
10//!
11//! #[derive(Identifiable, Queryable, PartialEq, Debug)]
12//! #[diesel(table_name = users)]
13//! pub struct User {
14//!     id: i32,
15//!     name: String,
16//! }
17//!
18//! #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
19//! #[diesel(belongs_to(User))]
20//! #[diesel(table_name = posts)]
21//! pub struct Post {
22//!     id: i32,
23//!     user_id: i32,
24//!     title: String,
25//! }
26//!
27//! # // Reading the query result requires reading memory allocated by the
28//! # // native sqlite library, which miri cannot track provenance for.
29//! # #[cfg(miri)]
30//! # fn main() {}
31//! # #[cfg(not(miri))]
32//! # fn main() {
33//! #     run_test().unwrap();
34//! # }
35//! #
36//! # fn run_test() -> QueryResult<()> {
37//! #     let connection = &mut establish_connection();
38//! #     use self::users::dsl::*;
39//! let user = users.find(2).get_result::<User>(connection)?;
40//! let users_post = Post::belonging_to(&user).first(connection)?;
41//! let expected = Post {
42//!     id: 3,
43//!     user_id: 2,
44//!     title: "My first post too".into(),
45//! };
46//! assert_eq!(expected, users_post);
47//! #     Ok(())
48//! # }
49//! ```
50//!
51//! Note that in addition to the `#[diesel(belongs_to)]` annotation, we also need to
52//! `#[derive(Associations)]`
53//!
54//! `#[diesel(belongs_to)]` is given the name of the struct that represents the parent.
55//! Both the parent and child must implement [`Identifiable`].
56//! The struct given to `#[diesel(belongs_to)]` must be in scope,
57//! so you will need `use some_module::User` if `User` is defined in another module.
58//!
59//! If the parent record is generic over lifetimes, they can be written as `'_`.
60//! You will also need to wrap the type in quotes until
61//! `unrestricted_attribute_tokens` is stable.
62//!
63//! ```rust
64//! # include!("../doctest_setup.rs");
65//! # use schema::{posts, users};
66//! # use std::borrow::Cow;
67//! #
68//! #[derive(Identifiable)]
69//! #[diesel(table_name = users)]
70//! pub struct User<'a> {
71//!     id: i32,
72//!     name: Cow<'a, str>,
73//! }
74//!
75//! #[derive(Associations)]
76//! #[diesel(belongs_to(User<'_>))]
77//! #[diesel(table_name = posts)]
78//! pub struct Post {
79//!     id: i32,
80//!     user_id: i32,
81//!     title: String,
82//! }
83//! #
84//! # fn main() {}
85//! ```
86//!
87//!
88//! By default, Diesel assumes that your foreign keys will follow the convention `table_name_id`.
89//! If your foreign key has a different name,
90//! you can provide the `foreign_key` argument to `#[diesel(belongs_to)]`.
91//! For example, `#[diesel(belongs_to(Foo, foreign_key = mykey))]`.
92//!
93//! Associated data is typically loaded in multiple queries (one query per table).
94//! This is usually more efficient than using a join,
95//! especially if 3 or more tables are involved.
96//! For most datasets,
97//! using a join to load in a single query transmits so much duplicate data
98//! that it costs more time than the extra round trip would have.
99//!
100//! You can load the children for one or more parents using
101//! [`belonging_to`]
102//!
103//! [`belonging_to`]: crate::query_dsl::BelongingToDsl::belonging_to
104//!
105//! ```rust
106//! # include!("../doctest_setup.rs");
107//! # use schema::users;
108//! # use schema::posts;
109//! #
110//! # #[derive(Debug, PartialEq, Identifiable, Queryable)]
111//! # pub struct User {
112//! #     id: i32,
113//! #     name: String,
114//! # }
115//! #
116//! # #[derive(Debug, PartialEq, Identifiable, Queryable, Associations)]
117//! # #[diesel(belongs_to(User))]
118//! # pub struct Post {
119//! #     id: i32,
120//! #     user_id: i32,
121//! #     title: String,
122//! # }
123//! #
124//! # // Reading the query result requires reading memory allocated by the
125//! # // native sqlite library, which miri cannot track provenance for.
126//! # #[cfg(miri)]
127//! # fn main() {}
128//! # #[cfg(not(miri))]
129//! # fn main() {
130//! #   use self::users::dsl::*;
131//! #   let connection = &mut establish_connection();
132//! #
133//! let user = users
134//!     .find(1)
135//!     .first::<User>(connection)
136//!     .expect("Error loading user");
137//! let post_list = Post::belonging_to(&user)
138//!     .load::<Post>(connection)
139//!     .expect("Error loading posts");
140//! let expected = vec![
141//!     Post {
142//!         id: 1,
143//!         user_id: 1,
144//!         title: "My first post".to_string(),
145//!     },
146//!     Post {
147//!         id: 2,
148//!         user_id: 1,
149//!         title: "About Rust".to_string(),
150//!     },
151//! ];
152//!
153//! assert_eq!(post_list, expected);
154//! # }
155//! ```
156//!
157//! If you're coming from other ORMs, you'll notice that this design is quite different from most.
158//! There you would have an instance method on the parent, or have the children stored somewhere on
159//! the posts. This design leads to many problems, including [N+1 query
160//! bugs][load-your-entire-database-into-memory-lol], and runtime errors when accessing an
161//! association that isn't there.
162//!
163//! [load-your-entire-database-into-memory-lol]: https://stackoverflow.com/q/97197/1254484
164//!
165//! In Diesel, data and its associations are considered to be separate. If you want to pass around
166//! a user and all of its posts, that type is `(User, Vec<Post>)`.
167//!
168//! Next lets look at how to load the children for more than one parent record.
169//! [`belonging_to`] can be used to load the data, but we'll also need to group it
170//! with its parents. For this we use an additional method [`grouped_by`].
171//!
172//! [`grouped_by`]: GroupedBy::grouped_by
173//! [`belonging_to`]: crate::query_dsl::BelongingToDsl::belonging_to
174//!
175//! [`belonging_to`] accepts a single parent or a collection of them,
176//! and its documentation carries a runnable example.
177//!
178//! Typically you will want to group up the children with their parents.
179//! In other ORMs, this is often called a `has_many` relationship.
180//! Diesel provides support for doing this grouping, once the data has been
181//! loaded.
182//!
183//! [`grouped_by`] is called on a `Vec<Child>` with a `&[Parent]`.
184//! The return value will be `Vec<Vec<Child>>` indexed to match their parent.
185//! Or to put it another way, the returned data can be passed to `zip`,
186//! and it will be combined with its parent.
187//!
188//! A runnable example lives on [`GroupedBy`].
189//!
190//! [`grouped_by`] can be called multiple times
191//! if you have multiple children or grandchildren.
192//!
193//! For example, this code will load some users,
194//! all of their posts,
195//! and all of the comments on those posts.
196//! Explicit type annotations have been added
197//! to make each line a bit more clear.
198//!
199//! ```rust
200//! # include!("../doctest_setup.rs");
201//! # use schema::{users, posts, comments};
202//! #
203//! # #[derive(Debug, PartialEq, Identifiable, Queryable)]
204//! # pub struct User {
205//! #     id: i32,
206//! #     name: String,
207//! # }
208//! #
209//! # #[derive(Debug, PartialEq, Identifiable, Queryable, Associations)]
210//! # #[diesel(belongs_to(User))]
211//! # pub struct Post {
212//! #     id: i32,
213//! #     user_id: i32,
214//! #     title: String,
215//! # }
216//! #
217//! # #[derive(Debug, PartialEq, Identifiable, Queryable, Associations)]
218//! # #[diesel(belongs_to(Post))]
219//! # pub struct Comment {
220//! #     id: i32,
221//! #     post_id: i32,
222//! #     body: String,
223//! # }
224//! #
225//! # // Reading the query result requires reading memory allocated by the
226//! # // native sqlite library, which miri cannot track provenance for.
227//! # #[cfg(miri)]
228//! # fn main() {}
229//! # #[cfg(not(miri))]
230//! # fn main() {
231//! #   let connection = &mut establish_connection();
232//! #
233//! let users: Vec<User> = users::table
234//!     .load::<User>(connection)
235//!     .expect("error loading users");
236//! let posts: Vec<Post> = Post::belonging_to(&users)
237//!     .load::<Post>(connection)
238//!     .expect("error loading posts");
239//! let comments: Vec<Comment> = Comment::belonging_to(&posts)
240//!     .load::<Comment>(connection)
241//!     .expect("Error loading comments");
242//! let grouped_comments: Vec<Vec<Comment>> = comments.grouped_by(&posts);
243//! let posts_and_comments: Vec<Vec<(Post, Vec<Comment>)>> =
244//!     posts.into_iter().zip(grouped_comments).grouped_by(&users);
245//! let result: Vec<(User, Vec<(Post, Vec<Comment>)>)> =
246//!     users.into_iter().zip(posts_and_comments).collect();
247//! let expected = vec![
248//!     (
249//!         User {
250//!             id: 1,
251//!             name: "Sean".to_string(),
252//!         },
253//!         vec![
254//!             (
255//!                 Post {
256//!                     id: 1,
257//!                     user_id: 1,
258//!                     title: "My first post".to_string(),
259//!                 },
260//!                 vec![Comment {
261//!                     id: 1,
262//!                     post_id: 1,
263//!                     body: "Great post".to_string(),
264//!                 }],
265//!             ),
266//!             (
267//!                 Post {
268//!                     id: 2,
269//!                     user_id: 1,
270//!                     title: "About Rust".to_string(),
271//!                 },
272//!                 vec![Comment {
273//!                     id: 2,
274//!                     post_id: 2,
275//!                     body: "Yay! I am learning Rust".to_string(),
276//!                 }],
277//!             ),
278//!         ],
279//!     ),
280//!     (
281//!         User {
282//!             id: 2,
283//!             name: "Tess".to_string(),
284//!         },
285//!         vec![(
286//!             Post {
287//!                 id: 3,
288//!                 user_id: 2,
289//!                 title: "My first post too".to_string(),
290//!             },
291//!             vec![Comment {
292//!                 id: 3,
293//!                 post_id: 3,
294//!                 body: "I enjoyed your post".to_string(),
295//!             }],
296//!         )],
297//!     ),
298//! ];
299//!
300//! assert_eq!(result, expected);
301//! # }
302//! ```
303//!
304//! And that's it.
305//! It may seem odd to have load, group, and zip be explicit separate steps
306//! if you are coming from another ORM.
307//! However, the goal is to provide simple building blocks which can
308//! be used to construct the complex behavior applications need.
309mod belongs_to;
310
311use core::hash::Hash;
312
313use crate::query_source::Table;
314
315pub use self::belongs_to::{BelongsTo, GroupedBy, TryGroupedByError};
316
317#[doc(inline)]
318pub use diesel_derives::Associations;
319
320/// This trait indicates that a struct is associated with a single database table.
321///
322/// This trait is implemented by structs which implement `Identifiable`,
323/// as well as database tables themselves.
324pub trait HasTable {
325    /// The table this type is associated with.
326    type Table: Table;
327
328    /// Returns the table this type is associated with.
329    fn table() -> Self::Table;
330}
331
332impl<T: HasTable> HasTable for &T {
333    type Table = T::Table;
334
335    fn table() -> Self::Table {
336        T::table()
337    }
338}
339
340impl<T: HasTable> HasTable for Option<T> {
341    type Table = T::Table;
342
343    fn table() -> Self::Table {
344        T::table()
345    }
346}
347
348impl<T: HasTable> HasTable for alloc::boxed::Box<T> {
349    type Table = T::Table;
350
351    fn table() -> Self::Table {
352        T::table()
353    }
354}
355
356impl<T: HasTable> HasTable for alloc::rc::Rc<T> {
357    type Table = T::Table;
358
359    fn table() -> Self::Table {
360        T::table()
361    }
362}
363
364impl<T: HasTable> HasTable for alloc::sync::Arc<T> {
365    type Table = T::Table;
366
367    fn table() -> Self::Table {
368        T::table()
369    }
370}
371
372// Implement HasTable for tuples of types which implement `HasTable` for
373// the same table.
374// This is useful for multi-column constraints like composite foreign keys.
375//
376// For example:
377// ```rust,ignore
378// // Given a table with columns (id, name)
379// type UserTable = <(users::id, users::name) as HasTable>::Table;
380// let table = <(users::id, users::name)>::table();
381// ```
382
383impl<T> HasTable for (T,)
384where
385    T: HasTable,
386{
387    type Table = T::Table;
388
389    fn table() -> Self::Table {
390        T::table()
391    }
392}
393
394macro_rules! has_table_tuples {
395    ($(
396        $Tuple:tt {
397            $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)*
398        }
399    )+) => {
400        $(
401            impl<_T, $($T),*> HasTable for (_T, $($T),*)
402            where
403                _T: HasTable,
404                $($T: HasTable<Table = _T::Table>,)*
405            {
406                type Table = _T::Table;
407
408                fn table() -> Self::Table {
409                    _T::table()
410                }
411            }
412        )+
413    };
414}
415
416impl<_T, T> HasTable for (_T, T) where _T: HasTable,
    T: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1> HasTable for (_T, T, T1) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2> HasTable for (_T, T, T1, T2) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3> HasTable for (_T, T, T1, T2, T3) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4> HasTable for (_T, T, T1, T2, T3, T4) where
    _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5> HasTable for (_T, T, T1, T2, T3, T4, T5) where
    _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table>, T11: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) where
    _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> HasTable
    for (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) where
    _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>
    HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) where
    _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>
    HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)
    where _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16) where _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17) where _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table>,
    T17: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18) where _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table>,
    T17: HasTable<Table = _T::Table>, T18: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19) where _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table>,
    T17: HasTable<Table = _T::Table>, T18: HasTable<Table = _T::Table>,
    T19: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table>, T11: HasTable<Table = _T::Table>,
    T12: HasTable<Table = _T::Table>, T13: HasTable<Table = _T::Table>,
    T14: HasTable<Table = _T::Table>, T15: HasTable<Table = _T::Table>,
    T16: HasTable<Table = _T::Table>, T17: HasTable<Table = _T::Table>,
    T18: HasTable<Table = _T::Table>, T19: HasTable<Table = _T::Table>,
    T20: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table>, T11: HasTable<Table = _T::Table>,
    T12: HasTable<Table = _T::Table>, T13: HasTable<Table = _T::Table>,
    T14: HasTable<Table = _T::Table>, T15: HasTable<Table = _T::Table>,
    T16: HasTable<Table = _T::Table>, T17: HasTable<Table = _T::Table>,
    T18: HasTable<Table = _T::Table>, T19: HasTable<Table = _T::Table>,
    T20: HasTable<Table = _T::Table>, T21: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table>, T11: HasTable<Table = _T::Table>,
    T12: HasTable<Table = _T::Table>, T13: HasTable<Table = _T::Table>,
    T14: HasTable<Table = _T::Table>, T15: HasTable<Table = _T::Table>,
    T16: HasTable<Table = _T::Table>, T17: HasTable<Table = _T::Table>,
    T18: HasTable<Table = _T::Table>, T19: HasTable<Table = _T::Table>,
    T20: HasTable<Table = _T::Table>, T21: HasTable<Table = _T::Table>,
    T22: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table>, T11: HasTable<Table = _T::Table>,
    T12: HasTable<Table = _T::Table>, T13: HasTable<Table = _T::Table>,
    T14: HasTable<Table = _T::Table>, T15: HasTable<Table = _T::Table>,
    T16: HasTable<Table = _T::Table>, T17: HasTable<Table = _T::Table>,
    T18: HasTable<Table = _T::Table>, T19: HasTable<Table = _T::Table>,
    T20: HasTable<Table = _T::Table>, T21: HasTable<Table = _T::Table>,
    T22: HasTable<Table = _T::Table>, T23: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table>, T11: HasTable<Table = _T::Table>,
    T12: HasTable<Table = _T::Table>, T13: HasTable<Table = _T::Table>,
    T14: HasTable<Table = _T::Table>, T15: HasTable<Table = _T::Table>,
    T16: HasTable<Table = _T::Table>, T17: HasTable<Table = _T::Table>,
    T18: HasTable<Table = _T::Table>, T19: HasTable<Table = _T::Table>,
    T20: HasTable<Table = _T::Table>, T21: HasTable<Table = _T::Table>,
    T22: HasTable<Table = _T::Table>, T23: HasTable<Table = _T::Table>,
    T24: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table>, T11: HasTable<Table = _T::Table>,
    T12: HasTable<Table = _T::Table>, T13: HasTable<Table = _T::Table>,
    T14: HasTable<Table = _T::Table>, T15: HasTable<Table = _T::Table>,
    T16: HasTable<Table = _T::Table>, T17: HasTable<Table = _T::Table>,
    T18: HasTable<Table = _T::Table>, T19: HasTable<Table = _T::Table>,
    T20: HasTable<Table = _T::Table>, T21: HasTable<Table = _T::Table>,
    T22: HasTable<Table = _T::Table>, T23: HasTable<Table = _T::Table>,
    T24: HasTable<Table = _T::Table>, T25: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26) where _T: HasTable,
    T: HasTable<Table = _T::Table>, T1: HasTable<Table = _T::Table>,
    T2: HasTable<Table = _T::Table>, T3: HasTable<Table = _T::Table>,
    T4: HasTable<Table = _T::Table>, T5: HasTable<Table = _T::Table>,
    T6: HasTable<Table = _T::Table>, T7: HasTable<Table = _T::Table>,
    T8: HasTable<Table = _T::Table>, T9: HasTable<Table = _T::Table>,
    T10: HasTable<Table = _T::Table>, T11: HasTable<Table = _T::Table>,
    T12: HasTable<Table = _T::Table>, T13: HasTable<Table = _T::Table>,
    T14: HasTable<Table = _T::Table>, T15: HasTable<Table = _T::Table>,
    T16: HasTable<Table = _T::Table>, T17: HasTable<Table = _T::Table>,
    T18: HasTable<Table = _T::Table>, T19: HasTable<Table = _T::Table>,
    T20: HasTable<Table = _T::Table>, T21: HasTable<Table = _T::Table>,
    T22: HasTable<Table = _T::Table>, T23: HasTable<Table = _T::Table>,
    T24: HasTable<Table = _T::Table>, T25: HasTable<Table = _T::Table>,
    T26: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27) where
    _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table>,
    T17: HasTable<Table = _T::Table>, T18: HasTable<Table = _T::Table>,
    T19: HasTable<Table = _T::Table>, T20: HasTable<Table = _T::Table>,
    T21: HasTable<Table = _T::Table>, T22: HasTable<Table = _T::Table>,
    T23: HasTable<Table = _T::Table>, T24: HasTable<Table = _T::Table>,
    T25: HasTable<Table = _T::Table>, T26: HasTable<Table = _T::Table>,
    T27: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> HasTable
    for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28) where
    _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table>,
    T17: HasTable<Table = _T::Table>, T18: HasTable<Table = _T::Table>,
    T19: HasTable<Table = _T::Table>, T20: HasTable<Table = _T::Table>,
    T21: HasTable<Table = _T::Table>, T22: HasTable<Table = _T::Table>,
    T23: HasTable<Table = _T::Table>, T24: HasTable<Table = _T::Table>,
    T25: HasTable<Table = _T::Table>, T26: HasTable<Table = _T::Table>,
    T27: HasTable<Table = _T::Table>, T28: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29>
    HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29)
    where _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table>,
    T17: HasTable<Table = _T::Table>, T18: HasTable<Table = _T::Table>,
    T19: HasTable<Table = _T::Table>, T20: HasTable<Table = _T::Table>,
    T21: HasTable<Table = _T::Table>, T22: HasTable<Table = _T::Table>,
    T23: HasTable<Table = _T::Table>, T24: HasTable<Table = _T::Table>,
    T25: HasTable<Table = _T::Table>, T26: HasTable<Table = _T::Table>,
    T27: HasTable<Table = _T::Table>, T28: HasTable<Table = _T::Table>,
    T29: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30>
    HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30)
    where _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table>,
    T17: HasTable<Table = _T::Table>, T18: HasTable<Table = _T::Table>,
    T19: HasTable<Table = _T::Table>, T20: HasTable<Table = _T::Table>,
    T21: HasTable<Table = _T::Table>, T22: HasTable<Table = _T::Table>,
    T23: HasTable<Table = _T::Table>, T24: HasTable<Table = _T::Table>,
    T25: HasTable<Table = _T::Table>, T26: HasTable<Table = _T::Table>,
    T27: HasTable<Table = _T::Table>, T28: HasTable<Table = _T::Table>,
    T29: HasTable<Table = _T::Table>, T30: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}
impl<_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
    T31> HasTable for
    (_T, T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
    T31) where _T: HasTable, T: HasTable<Table = _T::Table>,
    T1: HasTable<Table = _T::Table>, T2: HasTable<Table = _T::Table>,
    T3: HasTable<Table = _T::Table>, T4: HasTable<Table = _T::Table>,
    T5: HasTable<Table = _T::Table>, T6: HasTable<Table = _T::Table>,
    T7: HasTable<Table = _T::Table>, T8: HasTable<Table = _T::Table>,
    T9: HasTable<Table = _T::Table>, T10: HasTable<Table = _T::Table>,
    T11: HasTable<Table = _T::Table>, T12: HasTable<Table = _T::Table>,
    T13: HasTable<Table = _T::Table>, T14: HasTable<Table = _T::Table>,
    T15: HasTable<Table = _T::Table>, T16: HasTable<Table = _T::Table>,
    T17: HasTable<Table = _T::Table>, T18: HasTable<Table = _T::Table>,
    T19: HasTable<Table = _T::Table>, T20: HasTable<Table = _T::Table>,
    T21: HasTable<Table = _T::Table>, T22: HasTable<Table = _T::Table>,
    T23: HasTable<Table = _T::Table>, T24: HasTable<Table = _T::Table>,
    T25: HasTable<Table = _T::Table>, T26: HasTable<Table = _T::Table>,
    T27: HasTable<Table = _T::Table>, T28: HasTable<Table = _T::Table>,
    T29: HasTable<Table = _T::Table>, T30: HasTable<Table = _T::Table>,
    T31: HasTable<Table = _T::Table> {
    type Table = _T::Table;
    fn table() -> Self::Table { _T::table() }
}crate::for_each_tuple!(has_table_tuples);
417
418/// This trait indicates that a struct represents a single row in a database table.
419///
420/// This must be implemented to use associations.
421/// Additionally, implementing this trait allows you to pass your struct to `update`
422/// (`update(&your_struct)` is equivalent to
423/// `update(YourStruct::table().find(&your_struct.primary_key())`).
424///
425/// This trait is usually implemented on a reference to a struct,
426/// not on the struct itself. It can be [derived](derive@Identifiable).
427pub trait Identifiable: HasTable {
428    /// The type of this struct's identifier.
429    ///
430    /// For single-field primary keys, this is typically `&'a i32`, or `&'a String`
431    /// For composite primary keys, this is typically `(&'a i32, &'a i32)`
432    /// or `(&'a String, &'a String)`, etc.
433    type Id: Hash + Eq;
434
435    /// Returns the identifier for this record.
436    ///
437    /// This takes `self` by value, not reference.
438    /// This is because composite primary keys
439    /// are typically stored as multiple fields.
440    /// We could not return `&(String, String)` if each string is a separate field.
441    ///
442    /// Because of Rust's rules about specifying lifetimes,
443    /// this means that `Identifiable` is usually implemented on references
444    /// so that we have a lifetime to use for `Id`.
445    fn id(self) -> Self::Id;
446}
447
448#[doc(inline)]
449pub use diesel_derives::Identifiable;