2014-05-02 13 views
1

我是新來的rails和我使用Rails 4和attr_encrypted gem來加密一些字段(SSN,姓名,出生日期等),這些字段都將被插入到在varchar列中的數據庫。在表單視圖中,我使用date_select來生成出生日期字段(dob),但我無法將所選日期轉換爲字符串,因此attr_encrypted可以對其進行加密以便插入到數據庫中。attr_encrypted加密date_select表單幫助程序生成的日期

_form.html.erb

<%= f.label :dob %><br> 
<%= f.date_select :dob, { start_year: 1900, :order => [ :month, :day, :year ] , prompt: true, add_month_numbers: true, use_two_digit_numbers: true } %> 

給出的錯誤是質量分配錯誤,但我不知道如何/在哪裏(控制器/模型)來散列轉換成字符串,以便該attr_encrypted寶石將能夠加密它。什麼是實現這一目標的最佳方式?

回答

2

我發現attr_encrypted會破壞Rails自date_select的日期組合。我發現最簡單的解決方案是自己組裝日期字符串並重寫params散列。在你的控制器:

protected  

def compose_date(attributes, property) 
    # if the date is already composed, don't try to compose it 
    return unless attributes[property].nil? 

    keys, values = [], [] 

    # find the keys representing the components of the date 
    attributes.each_key {|k| keys << k if k.start_with?(property) } 

    # assemble the date components in the right order and write to the params 
    keys.sort.each { |k| values << attributes[k]; attributes.delete(k); } 
    attributes[property] = values.join("-") unless values.empty? 
end 

然後你就可以正常進行,一切都會好起來的:

def create 
    compose_date(params[:client], "dob") 

    @client = Client.new(params[:client]) 
    ... 
end 

編輯:我忘了這在第一,但我不得不做一些額外的工作來獲得日期在數據庫中正確存儲。 attr_encrypted gem總是希望存儲字符串,所以如果你的數據不是字符串,那麼你會想告訴它如何編組它。

我創建了一個模塊來處理數據加密:

module ClientDataEncryption 
    def self.included(base) 
    base.class_eval do 
     attr_encrypted :ssn, :key => "my_ssn_key" 
     attr_encrypted :first_name, :last_name, :key => "my_name_key" 
     attr_encrypted :dob, :key => "my_dob_key", 
        :marshal => true, :marshaler => DateMarshaler 
    end 
    end 

    class DateMarshaler 
    def self.dump(date) 
     # if our "date" is already a string, don't try to convert it 
     date.is_a?(String) ? date : date.to_s(:db) 
    end 

    def self.load(date_string) 
     Date.parse(date_string) 
    end 
    end 
end 

然後在我的客戶端模型包括它。

+0

對不起,我花了這麼久回覆,但非常感謝你!它完美的作品。我一直試圖弄清楚這個問題將近一週。我唯一需要做的事情是在編輯客戶端時,日期將字符串解析回日期,就是這樣。再次感謝。 – WillieG

0

我正在寫一份貸款申請表,並且在我的Owner模型的date_of_birth屬性中導致我在這裏與attr_encrypted發生同樣的問題。我發現沃利奧特曼的解決方案是必要的在我的應用程序中使用一些變化近乎完美:

  • 在嵌套形式使用該
  • 強參數
  • 多個模型實例

我逐字複製了DateMarshalercompose_date()方法,然後在我的控制器中,我添加了一個循環,遍歷我們在此處編輯的所有Owner對象。

def resource_params 
    params[:loan_application][:owners_attributes].each do |owner| 
    compose_date(owner[1], 'date_of_birth') 
    # If there were more fields that needed this I'd put them here 
    end 
    params.require(:loan_application).permit(:owners_attributes => 
    [ # Regular strong params stuff here ]) 
end 

它在任何數量的嵌套模型上都很有魅力!