【问题标题】:Alias for ActiveRecord columns in 'where' function“where”函数中 ActiveRecord 列的别名
【发布时间】:2014-09-15 05:27:08
【问题描述】:

我有一个外部只读数据库。 'LastName'、'CreateDate' 等列在哪里。我想为它创建某种别名。例如:

MyModel.select('LastName AS last_name').where(last_name: 'Somebody')

我不能修改数据库的结构,我不想处理查询结果。在完美的情况下,ActiveRecord 必须将任何函数中的 'LastName' 和 'last_name' 视为绝对等价的列。

【问题讨论】:

    标签: sql ruby-on-rails activerecord


    【解决方案1】:

    您必须为 SQL 和 Rails 执行操作。

    class MyModel
    
      def last_name=(v)
        return self.LastName=(v)
      end
    
      def last_name(reload = false)
         return LastName(reload)
      end
    
      scope :with_last_name, -> {
         select("#{MyModel.table_name}.*, LastName AS last_name")
      }
    end
    

    然后,你可以这样使用它:

    MyModel.with_last_name.where(:last_name => "Somebody")
    

    编辑

    你是对的。

    另一种解决方案是定义自己的where 方法,如下所示:

    def translate(h)
       return { :created_at => 'CREATEDAT' }[h] || h
    end
    
    def self.my_where(opts)
      opts2 = opts.inject({}) do |o,(h,v)|
        o[translate(h)] = v; o
      end
      return where(opts2)
    end
    

    然后,对M.my_where(:created_at => v) 的调用将调用M.where('CREATEDAT' => v)

    但您必须记住,其他所有方法(拥有、分组和很多)都不起作用。

    【讨论】:

    • 这是拐杖。我需要一种在 ActiveRecord 中大规模重新定义列的方法。此代码:MyModel.select("MyTable.CREATEDDATETIME AS created_at").where(created_at: DateTime.now) 对我不起作用。它引发“ActiveRecord::StatementInvalid: TinyTds::Error: Invalid column name 'created_at'”。我使用 Rails3,DB - MSSQL。
    • @user3240646 你说得对。我编辑了我的解决方案。不好。
    猜你喜欢
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多