use super::BelongsTo;
use crate::relation::has_many::class_to_snake_case;
pub fn default_belongs_to_foreign_key(related_class: &str) -> String {
let class_name = related_class
.rsplit(['\\', '/'])
.next()
.unwrap_or(related_class);
format!("{}_id", class_to_snake_case(class_name))
}
pub fn php_belongs_to(
related_class: &str,
parent_table: &str,
foreign_key: Option<&str>,
parent_pk: Option<&str>,
) -> BelongsTo {
BelongsTo {
foreign_key: foreign_key
.map(String::from)
.unwrap_or_else(|| default_belongs_to_foreign_key(related_class)),
parent_model: parent_table.to_string(),
parent_pk: parent_pk
.map(String::from)
.unwrap_or_else(|| "id".to_string()),
}
}
pub fn belongs_to_sql(parent_table: &str, parent_pk: &str, foreign_key_value: &str) -> String {
format!(
"SELECT * FROM {} WHERE {} = {}",
parent_table, parent_pk, foreign_key_value
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_belongs_to_default_fk_simple_class() {
assert_eq!(default_belongs_to_foreign_key("User"), "user_id");
assert_eq!(default_belongs_to_foreign_key("Order"), "order_id");
assert_eq!(default_belongs_to_foreign_key("Customer"), "customer_id");
}
#[test]
fn test_belongs_to_default_fk_multi_word_class() {
assert_eq!(default_belongs_to_foreign_key("OrderItem"), "order_item_id");
assert_eq!(default_belongs_to_foreign_key("UserRole"), "user_role_id");
}
#[test]
fn test_belongs_to_default_fk_with_namespace() {
assert_eq!(
default_belongs_to_foreign_key("app\\model\\User"),
"user_id"
);
assert_eq!(
default_belongs_to_foreign_key("app\\model\\OrderItem"),
"order_item_id"
);
assert_eq!(default_belongs_to_foreign_key("app/model/User"), "user_id");
}
#[test]
fn test_belongs_to_default_fk_all_uppercase_class() {
assert_eq!(default_belongs_to_foreign_key("URL"), "u_r_l_id");
}
#[test]
fn test_belongs_to_default_fk_differs_from_has_many() {
assert_eq!(
default_belongs_to_foreign_key("User"),
crate::relation::has_many::default_foreign_key("User")
);
}
#[test]
fn test_php_belongs_to_default_foreign_key() {
let rel = php_belongs_to("User", "users", None, None);
assert_eq!(rel.foreign_key, "user_id");
assert_eq!(rel.parent_model, "users");
assert_eq!(rel.parent_pk, "id");
}
#[test]
fn test_php_belongs_to_explicit_foreign_key() {
let rel = php_belongs_to("User", "users", Some("uid"), None);
assert_eq!(rel.foreign_key, "uid");
assert_eq!(rel.parent_model, "users");
assert_eq!(rel.parent_pk, "id");
}
#[test]
fn test_php_belongs_to_explicit_parent_pk() {
let rel = php_belongs_to("User", "users", Some("uid"), Some("pk"));
assert_eq!(rel.foreign_key, "uid");
assert_eq!(rel.parent_model, "users");
assert_eq!(rel.parent_pk, "pk");
}
#[test]
fn test_php_belongs_to_multi_word_related() {
let rel = php_belongs_to("OrderItem", "order_items", None, None);
assert_eq!(rel.foreign_key, "order_item_id");
assert_eq!(rel.parent_model, "order_items");
}
#[test]
fn test_php_belongs_to_with_namespace_related() {
let rel = php_belongs_to("app\\model\\User", "users", None, None);
assert_eq!(rel.foreign_key, "user_id");
}
#[test]
fn test_belongs_to_sql_numeric_fk() {
let sql = belongs_to_sql("users", "id", "1");
assert_eq!(sql, "SELECT * FROM users WHERE id = 1");
}
#[test]
fn test_belongs_to_sql_string_fk() {
let sql = belongs_to_sql("users", "id", "'abc-123'");
assert_eq!(sql, "SELECT * FROM users WHERE id = 'abc-123'");
}
#[test]
fn test_belongs_to_sql_custom_parent_pk() {
let sql = belongs_to_sql("users", "uid", "1");
assert_eq!(sql, "SELECT * FROM users WHERE uid = 1");
}
#[test]
fn test_belongs_to_sql_multi_word_table() {
let sql = belongs_to_sql("order_items", "id", "1");
assert_eq!(sql, "SELECT * FROM order_items WHERE id = 1");
}
#[test]
fn test_belongs_to_sql_aligns_sz_orm_core_pattern() {
let sql = belongs_to_sql("users", "id", "1");
assert!(sql.starts_with("SELECT * FROM users WHERE id = "));
}
#[test]
fn test_r5_php_belongs_to_default_fk_convention() {
assert_eq!(default_belongs_to_foreign_key("User"), "user_id");
assert_eq!(default_belongs_to_foreign_key("Order"), "order_id");
assert_eq!(default_belongs_to_foreign_key("Customer"), "customer_id");
assert_eq!(default_belongs_to_foreign_key("OrderItem"), "order_item_id");
}
#[test]
fn test_r5_php_belongs_to_explicit_fk_overrides_default() {
let rel = php_belongs_to("User", "users", Some("uid"), None);
assert_eq!(rel.foreign_key, "uid");
assert_ne!(rel.foreign_key, default_belongs_to_foreign_key("User"));
}
#[test]
fn test_r5_php_belongs_to_default_local_key_is_id() {
let rel = php_belongs_to("User", "users", None, None);
assert_eq!(rel.parent_pk, "id");
}
#[test]
fn test_r5_php_belongs_to_sql_pattern_matches_think_orm() {
let sql = belongs_to_sql("users", "id", "1");
assert_eq!(sql, "SELECT * FROM users WHERE id = 1");
}
#[test]
fn test_r5_php_belongs_to_returns_single_model() {
let rel = php_belongs_to("User", "users", None, None);
assert!(!rel.parent_model.is_empty());
assert!(!rel.foreign_key.is_empty());
assert!(!rel.parent_pk.is_empty());
}
#[test]
fn test_r5_php_belongs_to_namespace_handling() {
assert_eq!(
default_belongs_to_foreign_key("app\\model\\User"),
"user_id"
);
assert_eq!(
default_belongs_to_foreign_key("app\\model\\OrderItem"),
"order_item_id"
);
assert_eq!(
default_belongs_to_foreign_key("App\\Model\\User"),
"user_id"
);
}
#[test]
fn test_r5_php_belongs_to_fk_based_on_related_not_current() {
let rel = php_belongs_to("User", "users", None, None);
assert_eq!(rel.foreign_key, "user_id");
assert_ne!(rel.foreign_key, "order_id");
}
#[test]
fn test_r5_php_belongs_to_delegates_to_sz_orm_core() {
let rel = php_belongs_to("User", "users", None, None);
let _: &BelongsTo = &rel;
let relation = sz_orm_core::Relation::BelongsTo(rel.clone());
assert!(matches!(relation, sz_orm_core::Relation::BelongsTo(_)));
}
#[test]
fn test_integration_profile_belongs_to_user() {
let rel = php_belongs_to("User", "users", None, None);
assert_eq!(rel.foreign_key, "user_id");
assert_eq!(rel.parent_model, "users");
assert_eq!(rel.parent_pk, "id");
let sql = belongs_to_sql(&rel.parent_model, &rel.parent_pk, "1");
assert_eq!(sql, "SELECT * FROM users WHERE id = 1");
}
#[test]
fn test_integration_order_belongs_to_customer() {
let rel = php_belongs_to("Customer", "customers", Some("customer_id"), None);
assert_eq!(rel.foreign_key, "customer_id");
assert_eq!(rel.parent_model, "customers");
let sql = belongs_to_sql(&rel.parent_model, &rel.parent_pk, "100");
assert_eq!(sql, "SELECT * FROM customers WHERE id = 100");
}
#[test]
fn test_integration_contract_belongs_to_customer() {
let rel = php_belongs_to("Customer", "customers", None, None);
assert_eq!(rel.foreign_key, "customer_id");
assert_eq!(rel.parent_model, "customers");
let sql = belongs_to_sql(&rel.parent_model, &rel.parent_pk, "200");
assert_eq!(sql, "SELECT * FROM customers WHERE id = 200");
}
#[test]
fn test_integration_order_item_belongs_to_order() {
let rel = php_belongs_to("Order", "orders", None, None);
assert_eq!(rel.foreign_key, "order_id");
assert_eq!(rel.parent_model, "orders");
let sql = belongs_to_sql(&rel.parent_model, &rel.parent_pk, "50");
assert_eq!(sql, "SELECT * FROM orders WHERE id = 50");
}
}