1

Rails 4 とattr_encryptedgem を使用していくつかのフィールド (SSN、名前、生年月日など) を暗号化しています。これらはすべてデータベースのvarchar列に挿入されます。フォーム ビューdate_selectで生年月日フィールド (dob) を生成するために使用していますが、選択した日付を文字列に変換attr_encryptedしてデータベースに挿入するために暗号化するのに問題があります。

_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与えられたエラーは大量割り当てエラーですが、 gem が暗号化できるようにハッシュを文字列に変換する方法/場所 (コントローラー/モデル) がわかりません。これを達成するための最良の方法は何ですか?

4

2 に答える 2

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

次に、それをクライアント モデルに含めました。

于 2014-05-02T21:40:17.043 に答える
0

私はローン申請書を書いていますがattr_encryptedOwnerモデルのdate_of_birth属性で同じ問題が発生していたため、ここに来ました。Wally Altman のソリューションは、私のアプリケーションで使用するために必要ないくつかの変更を加えることで、ほぼ完璧であることがわかりました。

  • これをネストされた形式で使用する
  • 強いパラメータ
  • 複数のモデル インスタンス

DateMarshalerメソッドとメソッドをそのままコピーしてから、ここで編集しているcompose_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

ネストされたモデルの数に関係なく、魔法のように機能しました!

于 2015-03-30T14:40:56.877 に答える