2017-09-17 3 views
0

私は初心者のRuby開発者です。私はDBスキーマと異なる名前で属性を設定する方法

は、次のスキーマに

create_table "sync_tasks", force: :cascade do |t| 
    t.string "name" 
    t.string "path" 
    t.string "task_type" 
    t.string "status" 
    t.boolean "async", default: false 
    t.boolean "direct_download", default: true 
    t.datetime "created_at", null: false 
    t.datetime "completed_at" 
    t.datetime "updated_at", null: false 
    end 

を考慮し、私は、次のペイロード

{ 
    "name" : "Sync /var/www/", 
    "path" : "/var/www", 
    "directDownload": true, 
    "async" : false, 
    "taskType" : "directory" 
} 

としようとしていDBスキーマで定義されているよりも、異なる属性名を持つActiveRecordモデルを作成する方法を見つけ出すことはできませんそのようなモデルを作成する

class SyncTask < ApplicationRecord 
    TYPE_DB='db' 
    TYPE_FILE='file' 
    TYPE_DIRECTORY='directory' 

    def initialize(params) 
# super 
    @task_type = params[:taskType] 
    @direct_download = params[:directDownload] 
    @path = params[:path] 
    @status = params[:status] 
    @async = params[:async] 
    end 
end 

私はそれはそれは私がコメントを解除する場合には、次のエラー

#<NoMethodError: undefined method `task_type' for #<SyncTask not initialized>> 

をスロー

<NoMethodError: undefined method `[]' for nil:NilClass> 

はまた、私はその

new_task = SyncTask.new(allowed_task_params) 
    new_task.task_type 

のようにフィールドにアクセスすることはできませんよ、エラーがスローされます保存しようとするとスーパーコールは別のエラーを返します

#<ActiveModel::UnknownAttributeError: unknown attribute 'taskType' for SyncTask.> 

私は間違っていますか?異なる属性名を使用し、自分でモデルを初期化するにはどうすればよいですか?

おかげであなたはtransform the keys、例えばでき

答えて

1

=> payload = { "name": "Sync /var/www/", "path": "/var/www", "directDownload": true, "taskType": "directory" } 
=> h = payload.transform_keys { |key| key.to_s.underscore } # only since v4.0.2 
=> h = Hash[payload.map { |(k, v)| [k.to_s.underscore, v] }] # before v.4.0.2 
#> {"name"=>"Sync /var/www/", "path"=>"/var/www", "direct_download"=>true, "task_type"=>"directory"} 
=> new_task = SyncTask.new(h) 

あなたはARモデルのinitializeメソッドを使用しないでください。まだinitializeを使用する必要がある場合は、after_initializeフックを使用してください。初期化でスーパーを宣言する必要があるので、コールバックを使用するのが最善です。

+0

カスタムイニシャライザをまったく提供する方法はありませんか?私はRubyのような動的な言語からのこのような動作を期待していません – bxfvgekd

+0

それは動作しますが、私はこの解決策が嫌いです。 – bxfvgekd

+0

この場合、モデルの実装の詳細に依存しており、アプリケーションの異なるレイヤーを分離することはできません。本当に失望します。 – bxfvgekd

関連する問題