Trait GroupedBy

Source
pub trait GroupedBy<'a, Parent>: IntoIterator + Sized {
    // Required method
    fn grouped_by(self, parents: &'a [Parent]) -> Vec<Vec<Self::Item>>;

    // Provided method
    fn try_grouped_by(
        self,
        parents: &'a [Parent],
    ) -> Result<Vec<Vec<Self::Item>>, TryGroupedByError<Self::Item>> { ... }
}
Expand description

The grouped_by function groups records by their parent.

grouped_by is called on a Vec<Child> with a &[Parent]. The return value will be Vec<Vec<Child>> indexed to match their parent. Or to put it another way, the returned data can be passed to zip, and it will be combined with its parent. This function does not generate a GROUP BY SQL statement, as it operates on data structures already loaded from the database

Child refers to the “many” part of a “one to many” relationship. It “belongs to” its parent Parent refers to the “one” part of a “one to many” relationship and can “have many” children. The child always has a foreign key, which refers to its parent’s primary key. In the following relationship, User has many Posts, so User is the parent and Posts are children.

§Example

let users = users::table.load::<User>(connection)?;
let posts = Post::belonging_to(&users)
    .load::<Post>(connection)?
    .grouped_by(&users);
let data = users.into_iter().zip(posts).collect::<Vec<_>>();

let expected_data = vec![
    (
        User { id: 1, name: "Sean".into() },
        vec![
            Post { id: 1, user_id: 1, title: "My first post".into() },
            Post { id: 2, user_id: 1, title: "About Rust".into() },
        ],
    ),
    (
        User { id: 2, name: "Tess".into() },
        vec![
            Post { id: 3, user_id: 2, title: "My first post too".into() },
        ],
    ),
];

assert_eq!(expected_data, data);

See the module documentation for more examples

Required Methods§

Source

fn grouped_by(self, parents: &'a [Parent]) -> Vec<Vec<Self::Item>>

See the trait documentation.

Provided Methods§

Source

fn try_grouped_by( self, parents: &'a [Parent], ) -> Result<Vec<Vec<Self::Item>>, TryGroupedByError<Self::Item>>

A fallible alternative to GroupedBy::grouped_by.

If any child record could not be grouped, either because of a NULL foreign key, or a parent record with a matching key could not be found, this function should return Err, with all successfully grouped records, as well as any ungrouped records.

§Errors

If a parent record could not be found for any of the child records, this function should return the TryGroupedByError. Every supplied record should be contained in the returned error, either in the grouped field, if it was successfully grouped, or the ungrouped field, if it was not possible to associate with a parent record.

§Examples
let users = users::table.load::<User>(connection)?;
let mut posts = Post::belonging_to(&users)
    .load::<Post>(connection)?;
posts.push(
    Post { id: 9, user_id: 42, title: "A post returned from another query".into() }
);
let TryGroupedByError { grouped, ungrouped, .. } = posts.try_grouped_by(&users).unwrap_err();

let grouped_data = users.into_iter().zip(grouped).collect::<Vec<_>>();

let expected_grouped_data = vec![
    (
        User { id: 1, name: "Sean".into() },
        vec![
            Post { id: 1, user_id: 1, title: "My first post".into() },
            Post { id: 2, user_id: 1, title: "About Rust".into() },
        ],
    ),
    (
        User { id: 2, name: "Tess".into() },
        vec![
            Post { id: 3, user_id: 2, title: "My first post too".into() },
        ],
    ),
];

let expected_ungrouped_data = vec![
    Post { id: 9, user_id: 42, title: "A post returned from another query".into() }
];

assert_eq!(expected_grouped_data, grouped_data);
assert_eq!(expected_ungrouped_data, ungrouped);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<'a, Parent: 'a, Child, Iter> GroupedBy<'a, Parent> for Iter
where Iter: IntoIterator<Item = Child>, Child: BelongsTo<Parent>, &'a Parent: Identifiable, <&'a Parent as Identifiable>::Id: Borrow<Child::ForeignKey>,