Skip to content

Cleanup: remove email field on User in Rust code #1888

Closed
@carols10cents

Description

@carols10cents

This is for someone who likes fixing compiler errors and knows or wants to learn about diesel :)

As of this PR, I'm pretty sure we don't use the email field on User anywhere directly anymore (and if we aren't, we shouldn't be). Instead, we have an emails table that joins to users.

So we can clean this field up and be less confusing about where the user's email is.

The first step is removing all usage of this field from the Rust code, but leaving the column on the users table in the database. Once the Rust code is no longer using the column, we can safely migrate the database to drop that column.

But this issue is for just the first step. The way I'd go about it, which isn't the only way so feel free to go about this the way you'd like, is to remove this line from the User struct definition and try to compile.

A lot of the error messages are going to be because the default behavior of diesel is to select all columns of a table and expect the struct definition to match. Removing the email field from the struct will break that assumption. We need to change the Rust code to never select the email field from the database. We have this problem with krate too, which has a column having to do with full text search that we never want to select in the Rust code.

The way the krate code works is it defines a type alias and a constant named ALL_COLUMNS:

/// We literally never want to select `textsearchable_index_col`
/// so we provide this type and constant to pass to `.select`
type AllColumns = (
crates::id,
crates::name,
crates::updated_at,
crates::created_at,
crates::downloads,
crates::description,
crates::homepage,
crates::documentation,
crates::repository,
crates::max_upload_size,
);
pub const ALL_COLUMNS: AllColumns = (
crates::id,
crates::name,
crates::updated_at,
crates::created_at,
crates::downloads,
crates::description,
crates::homepage,
crates::documentation,
crates::repository,
crates::max_upload_size,
);

And then everywhere that we select a krate from the database, use that constant instead. For example, selecting all crates happens with the all function:

pub fn all() -> All {
crates::table.select(ALL_COLUMNS)
}
which uses the ALL_COLUMNS constant and another type alias named All:
type All = diesel::dsl::Select<crates::table, AllColumns>;

Other convenience functions like Crate::by_name:

pub fn by_name(name: &str) -> ByName<'_> {
Crate::all().filter(Self::with_name(name))
}
chain filter calls off all to avoid having to duplicate the .select(ALL_COLUMNS) bit.

Extracting some helper functions might be an intermediate step that can be done in a separate commit from, but informed by, the fixes to the compilation errors. In other words, the errors can tell you where we're currently selecting users from the database directly that we could maybe be using a helper function instead. Extracting those could be done in a commit that passes tests as it would be a smaller refactoring that wouldn't change behavior. Then the commit that removes the field from the struct would need fewer changes in fewer places, hopefully. This may not actually be the case, or may not actually make the changes easier, and it may be just the way I work. If this paragraph doesn't make sense, ignore it!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions