【问题标题】:How to set attributes with different names than a DB schema如何设置名称与数据库模式不同的属性
【发布时间】:2017-09-17 16:12:07
【问题描述】:

我是一名新手 Ruby 开发人员。我不知道如何创建一个 ActiveRecord 模型,其属性名称与 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"
}

并尝试像这样创建我的模型

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 `[]' for nil:NilClass>

我也无法访问这样的字段

  new_task = SyncTask.new(allowed_task_params)
  new_task.task_type

它会抛出以下错误

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

如果我取消注释超级调用它会给出另一个错误

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

我做错了什么?如何使用不同的属性名称并自行初始化模型?

谢谢

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 activerecord orm


    【解决方案1】:

    您可以transform the keys,例如:

    => 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 挂钩。因为用initialize我们要声明super,所以最好用callback。

    【讨论】:

    • 根本没有办法提供自定义初始化器?我没想到像 Ruby 这样的动态语言会出现这种行为
    • 它有效,但我不喜欢这个解决方案,功能真的很差。
    • 在这种情况下你依赖于模型实现细节并且你不能分离你的应用程序的不同层,真的很失望
    • Rails 有一些规则,如果你不喜欢它们,就不要使用 Rails。
    • 有趣的实现,不过感谢 asnwer) spasibo :)
    猜你喜欢
    • 1970-01-01
    • 2015-09-13
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    相关资源
    最近更新 更多