2015-04-19 91 views
0

在我的模型User中,已經存在一個自動遞增的id列。現在我打算給用戶一個唯一的名字。基於兩個字段查詢導軌模型,其中一個有時爲空

現在,用戶將不會在註冊過程中要求,所以在默認情況下,我想列"user" + id時調用像

user.profile_name #=> should return "user#{user.id}" if nil 

我不想要複製數據,所以我想保留字段nil,直到用戶輸入一個。

所以,我想創建一個自定義函數(或重寫​​如果可能的話)

# model User.rb 
def get_identifier 
    profile_name ? profile_name : "user#{id}" 
end 

而且使用where找到用戶

id, user = params[:identifier], nil 
if id[0..3] == "user" 
    user = User.find_by_id(id[3..-1].to_num) 
else 
    user = User.find_by profile_name: id 

,但這似乎並不是一個軌道辦法。即使在查詢時,我也必須處理這兩種情況。

有沒有什麼辦法可以簡化這個我在失蹤的Rails?否則可以改進目前的方法(除了將代碼重構爲方法)?

P.S問題用我正在使用的版本進行適當標記。 Ruby版本 - 2.1.5

+0

如果有人可以更好地標題,請自由編輯。 –

回答

1

我想以這個答案作爲序言,我的觀點是,您對數據實際上只是id的「複製數據」的猶豫可能是不必要的。它不是用戶可編輯的或任何東西,所以我不確定如果不計算數據庫大小中的字節會帶來什麼壞處。

鑑於問題的制約,我想看看在這樣一個實現:

class User 
    def self.find_by_profile_name(profile_name) 
    where(profile_name: profile_name).first || find_by_default_profile_name(profile_name) 
    end 

    def self.find_by_default_profile_name(profile_name) 
    where(id: DefaultProfileName.from_profile_name(profile_name).id) 
    end 
end 


class DefaultProfileName 
    attr_accessor :id 

    def self.from_profile_name(profile_name) 
    new(profile_name.sub('user', '')) 
    end 

    def initialize(id) 
    self.id = id 
    end 

    def to_s 
    "user#{id}" 
    end 
end 

我敢肯定,這還有待改進,但主要的外賣是封裝默認的配置文件名功能在其自己的類中可以使這些功能包含在內並且更易於管理。

+0

我喜歡這個解決方案..通過複製數據,我意味着浪費資源來保存這樣的數據:'id:1,profile_name:user1',當我們可以在代碼中構建它時。另外通過*我相信這可以改進*你是什麼意思?這怎麼能改進呢? –

+0

關於數據重複:我不認爲如果你開始爲每個記錄提供一個額外的字符串,你的服務器將會非常不安。關於可能的改進:這只是一個免責聲明,我所提供的代碼可能不是給定業務需求的絕對最終結果,但我相信這是一個很好的開始。 –

+0

好的..我不熟悉數據庫,所以我願意接受它..但是,如何保存該ID,因爲ID將只在保存記錄後可用?我應該在保存後獲得id並再次更新'profile_name'並再次存儲它? –

0

我認爲您需要爲現有用戶回填​​。否則,你可能會遇到各種有趣的問題。

例如:有現有用戶12,都沒有一個唯一的用戶名呢。用戶1具有​​user1,模擬爲具有user2作爲​​user2用戶2。現在,用戶1決定設置一個​​,他將其​​設置爲user2,此時什麼是唯一​​--至少從Rails驗證器的角度來看。

爲避免此問題:請務必爲現有用戶設置獨特的​​和回填​​。

+0

我想到了這一點,只是沒有指定我會通過代碼'「_user#{user.id}」添加,並且用戶無法使用用戶界面中的'_'開始他們的配置文件名稱。 –

相關問題