drd*_*man 5 ruby orm model left-join sequel
我有一个传统的PostgreSQL数据库,它将一个模型分成两个表,它们之间有一对一的映射.
CREATE TABLE auth_user (
id SERIAL,
username VARCHAR(30),
email VARCHAR(75),
password VARCHAR(64),
first_name VARCHAR(75),
last_name VARCHAR(75)
)
CREATE TABLE user_profile (
user_id INTEGER REFERENCES auth_User.id,
phone VARCHAR(32)
)
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法更改数据库结构.
我想将它用作单个续集模型.从数据库中检索数据按预期工作:
class User < Sequel::Model
end
# Variant 1: using LEFT JOIN
#User.set_dataset DB[:auth_user].left_join(:user_profile, :user_id => :id)
# Variant 2: using two FROM tables
User.set_dataset DB[:auth_user, :user_profile]\
.where(:auth_user__id => :user_profile__user_id)
user = User[:username => "root"] # This works.
Run Code Online (Sandbox Code Playgroud)
但是,保存模型失败:
user.set :first_name => "John"
user.save # This fails.
Run Code Online (Sandbox Code Playgroud)
如果我使用数据集的第一个变体(with left_join),我会收到" Need multiple FROM tables if updating/deleting a dataset with JOINs"错误.如果我使用第二个变体,它仍然会失败:" PG::Error: ERROR: column "phone" of relation "auth_user" does not exist LINE 1: ..."email" = 'nobody@example.org', "password" = '!', "phone"..."
有没有办法让Sequel无缝发出两个UPDATE语句?(同样的问题也适用于INSERT).
您可以拥有使用连接数据集的 Sequel 模型,但没有简单的方法来保存此类模型。
就我个人而言,我会使用多对一关系、嵌套属性和钩子来实现您想要的功能:
class UserProfile < Sequel::Model(:user_profile)
end
class User < Sequel::Model(:auth_user)
many_to_one :user_profile, :key=>:id, :primary_key=>:user_id
plugin :nested_attributes
nested_attributes :user_profile
def phone
user_profile.phone
end
def phone=(v)
user_profile.phone = v
end
def user_profile
if s = super
s
else
self.user_profile_attributes = {}
super
end
end
def before_destroy
user_profile.destroy
super
end
def before_create
user_profile
super
end
def after_update
super
user_profile.save
end
end
Run Code Online (Sandbox Code Playgroud)
我还没有测试过,但类似的东西应该有效。如果您遇到问题,您可能应该在续集讨论 Google 群组上发帖。
| 归档时间: |
|
| 查看次数: |
2404 次 |
| 最近记录: |