Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign uphas_many/belongs_to breaks with an underscore #86
Comments
sgrif
added this to the
0.4.2 milestone
Jan 11, 2016
This comment has been minimized.
|
In addition to just flat out fixing this problem, I'd also like to decouple the table name from the struct name, and allow a |
sgrif
modified the milestones:
0.5,
0.4.2
Jan 11, 2016
This comment has been minimized.
|
The decoupling would probably help a lot, as it looks like it has trouble with any edge case pluralization as well |
This comment has been minimized.
|
Yeah, it literally is .to_lowercase + s right now. We can make it On Mon, Jan 11, 2016, 5:46 PM Matt Casper notifications@github.com wrote:
|
This comment has been minimized.
|
|
sgrif
added
bug
internal or unreleased api
labels
Jan 12, 2016
added a commit
that referenced
this issue
Jan 12, 2016
sgrif
referenced this issue
Jan 12, 2016
Merged
Allow structs to be annotated with `#[table_name="foo"]` #87
This comment has been minimized.
|
Also I didn't mention it earlier, but also keep in mind that I've left associations out of the public API of the released crate, as I'm not happy with the current design and it may change further (it also likely requires the lattice rule coming w/ specialization to implement properly) |
This comment has been minimized.
|
So I've been starting to think more heavily about this, and specifically how to avoid duplicating a lot of information when dealing with non-standard tables and primary keys. An interesting thing about the Just spitballing some thoughts here. Scoping to impl ::diesel::BelongingToDsl<Bar> for Foo {
type Output = ::diesel::helper_types::FindBy<
foos::table,
foos::bar_id,
i32,
>;
fn belonging_to(model: &Bar) -> Self::Output {
foos::table.filter(foos::bar_id.eq(model.id.clone()))
}
}
impl ::diesel::JoinTo<bars::table> for foos::table {
fn join_sql(&self, out: &mut ::diesel::query_builder::QueryBuilder)
-> ::diesel::query_builder::BuildQueryResult
{
try!(bars::table.from_clause(out));
out.push_sql(" ON ");
foos::bar_id.eq(bars::table.primary_key()).to_sql(out)
}
}So I guess really all we need is something like trait Identifiable {
type Table: Table;
type Pk: AsExpression<Self::Table::PrimaryKey::SqlType>;
fn table() -> Self::Table;
fn primary_key(&self) -> Self::Pk;
}Now the question is where do we actually generate this. Are we fine with just requiring a It's worth noting that all of this is focusing around the idea that these structs will represent a single row on a single table. While that's counter to the design of the framework overall, I think that more or less has to be a given when we start talking about associations (unless we want to explore the idea that you'd have a single struct to represent both sides, but I don't think that'll work well with one-to-many, and would inhibit code re-use). It's also worth noting that we never actually use the argument to With all of this in mind, I'm thinking that we should change the API to impl ::diesel::BelongingToDsl<Bar> for Foo {
type Output = ::diesel::helper_types::FindBy<
foos::table,
foos::bar_id,
i32,
>;
fn belonging_to(model: &Bar) -> Self::Output {
foos::table.filter(foos::bar_id.eq(<Bar as Identifiable>::primary_key(model)))
}
}
impl ::diesel::JoinTo<<Bar as Identifiable>::Table> for foos::table {
fn join_sql(&self, out: &mut ::diesel::query_builder::QueryBuilder)
-> ::diesel::query_builder::BuildQueryResult
{
try!(<Bar as Identifiable>::table().from_clause(out));
out.push_sql(" ON ");
foos::bar_id.eq(<Bar as Identifiable>::table().primary_key()).to_sql(out)
}
}This does mean that you can't have an association using a primary key other than that of the table. I think that's fine, as the point is that we're equating with a single row, and I've never seen a good use case for changing the primary key of an association in Rails. This will be a little bit more murky when it comes to At some point it will also be the thing that makes you able to get Perhaps at the heart of this is figuring out exactly what associations are meant to do. I do like If that's the case, maybe we need to separate out the relationships between tables from the relationships between structs. The biggest problem there is that we no longer have a place for you to actually annotate a table. I need to spike some more on what I want to be able to do with |
mcasper commentedJan 11, 2016
The has_many/belongs_to codegen annotations don't seem to be able to handle a table name consisting of multiple words and underscores, as it smashes all the words together when searching for the module name. The following code fails to compile:
Giving the following error:
The expansion is looking for
soccerballs::tableand friends, when it should be looking forsoccer_balls::tableand friends.