2012-06-13 48 views
4

我有一个传统的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) 
) 

不幸的是,我无法更改数据库结构。

我想用它作为单一的续集模型。从数据库Retreiving数据按预期工作:

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. 

然而,保存模型失败:

user.set :first_name => "John" 
user.save      # This fails. 

如果我使用的数据集的第一变型(与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" = '[email protected]', "password" = '!', "phone"...

有没有办法让续集无缝地发出两条UPDATE语句? (同样的问题也适用于INSERTs)。

回答

4

你可以有一个使用连接数据集的Sequel模型,但没有简单的方法来保存这样的模型。

就个人而言,我会用一个many_to_one关系,嵌套的属性,和挂钩你想要的东西:

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 

我没有测试过这一点,但像它应该工作。如果您遇到问题,您可能需要在续集Google Group上发帖。