2012-06-13 47 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上發帖。