activerecord查询

时间:2016-07-25 19:59:00

标签: ruby-on-rails activerecord

大家都收到此错误,我认为它已附加到此查询中。

ERROR -- : Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use 
near '? AND `profile_activity`.`entity_type` IN (?, ?, ?, ?)  ORDER BY `profile_activi' at line 1: 

   EXPLAIN SELECT  `profile_activity`.`date_created`, `profile_activity`.`entity_id`, `profile_activity`.`entity_type`, `profile_activity`.`activity_type` 
   FROM `profile_activity` 
   WHERE `profile_activity`.`user_id` = 197056 
       AND `profile_activity`.`activity_type` = ? 
       AND `profile_activity`.`entity_type` IN (?, ?, ?, ?)  
   ORDER BY `profile_activity`.`date_created` DESC 
   LIMIT 19 OFFSET 0

这是活动记录查询

    ProfileActivity
      .select(:date_created, :entity_id, :entity_type, :activity_type)
      .where(activity_type: 'V', entity_type: ['A', 'B', 'C', 'WL'])
      .order(date_created: :desc)
      .limit(limit)
      .offset(offset)

看起来它不会解释第一个字符串'V',依此类推。不知道为什么会这样。感谢您对此的任何帮助。

数据库列是entity_type和activity_type的CHARS。

EDIT ***

个人资料活动模型

class ProfileActivity < ActiveRecord::Base
  self.table_name = 'profile_activity'

  belongs_to :user
  has_one :agency, foreign_key: :agency_id, primary_key: :entity_id
  has_one :company, foreign_key: :company_id, primary_key: :entity_id
  has_one :company_brand, foreign_key: :brand_id, primary_key: :entity_id

  scope :views, -> (limit, offset) {
  select(:date_created, :entity_id, :entity_type, :activity_type).where(activity_type: 'V', entity_type: ['A', 'B', 'C', 'WL']).order(date_created: :desc).limit(limit).offset(offset)
  }

  scope :most_recent_views_by_user, -> (user_id) {
    sql        = ProfileActivity.where(user_id: user_id).to_sql
    table_name = ProfileActivity.table_name
    select(:date_created, :entity_id, :entity_type, :activity_type)
.where(activity_type: 'V', entity_type: ['A', 'B', 'C'])
.order(date_created: :desc).limit(10)
.from("(#{sql}) as #{table_name}")
    }
end

my_activity_controller.rb

def user_activities
activities = []

if current_user
  decoder        = HTMLEntities.new
  activity_views = ProfileActivity.where(user_id: current_user.id).views(params[:limit], params[:offset])

  activity_views.each do |a|
    next if (a.created_at.nil? || a.entity_id == 0)

    begin
      case a.entity_type
      when 'B'
        business            = Business.find_by(id: a.entity_id)
        entity_name         = decoder.decode(business.name)
        entity_type         = 'Business'
        entity_abbreviation = 'B'
      else
        entity_name = nil
        entity_type = nil
      end

      case a.activity_type
      when 'D'
        activity_type = 'downloaded'
      when 'P'
        activity_type = 'printed'
      when 'V'
        activity_type = 'viewed'
      else
        activity_type = nil
      end

      case a.entity_type
      when 'B'
        url = business_profile_path(a.entity_id)
      else
        url = nil
      end

      activities << { date:                a.created_at,
                      url:                 url,
                      entity_name:         entity_name,
                      entity_type:         entity_type,
                      entity_abbreviation: entity_abbreviation,
                      activity_type:       activity_type }
    rescue => e
      ErrorHandler.notify_exception(e, env: env) rescue nil
    end
  end
end

1 个答案:

答案 0 :(得分:0)

  
    

这个答案适用于Rails版本4.2

  

我最好的猜测是ActiveRecord无法识别entity_typeactivity_type的类型。这是因为,ActiveRecord不支持CHAR数据类型。参考:https://stackoverflow.com/a/17918118/976880

您可以在模型中明确指定这些列的类型:

class ProfileActivity < ActiveRecord::Base
  self.table_name = 'profile_activity'

  attribute :entity_type, ActiveRecord::Type::String.new
  attribute :activity_type, ActiveRecord::Type::String.new
  ...
end

这样ActiveRecord将它们视为字符串并生成正确的查询。

修改

如果列类型不是CHAR,则可以添加迁移,将其更改为VARCHAR,而不是执行上述操作。