TypeError:没有将Hash隐式转换为String

时间:2019-07-18 02:36:07

标签: ruby-on-rails ruby typeerror

我有一个包含{p>的seeds.rb文件

User.find_or_create_by([
  { name: 'Root', email: 'root@sam-media.com', groups: {role: 'root', countries: :all}, password: 'asdfasdf' },
  { name: 'Admin', email: 'admin@sam-media.com', groups: {role: 'admin', countries: :all}, password: 'asdfasdf' },
  { name: 'Dev', email: 'dev@sam-media.com', groups: {role: 'dev', countries: :all}, password: 'asdfasdf' },
  { name: 'BO', email: 'bo@sam-media.com', groups: {role: 'root', countries: :all}, password: 'asdfasdf' },
  { name: 'Affiliate', email: 'uk@sam-media.com', groups: {role: 'affiliate', countries: 'uk', gateways: ['Oxygen8']}, password: 'asdfasdf' }
])

但是当我运行rake db:seed时,出现此错误:

/app # rake db:seed
rake aborted!
TypeError: no implicit conversion of Hash into String
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/sanitization.rb:125:in `match?'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/sanitization.rb:125:in `sanitize_sql_array'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/sanitization.rb:26:in `sanitize_sql_for_conditions'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/relation/where_clause_factory.rb:14:in `build'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/relation/query_methods.rb:591:in `where!'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/relation/query_methods.rb:584:in `where'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/relation/finder_methods.rb:81:in `find_by'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/relation.rb:164:in `find_or_create_by'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/querying.rb:8:in `find_or_create_by'
/app/db/seeds.rb:9:in `<main>'
/usr/local/bundle/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:50:in `load'
/usr/local/bundle/gems/bootsnap-1.3.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:50:in `load'
/usr/local/bundle/gems/activesupport-5.2.2/lib/active_support/dependencies.rb:285:in `block in load'
/usr/local/bundle/gems/activesupport-5.2.2/lib/active_support/dependencies.rb:257:in `load_dependency'
/usr/local/bundle/gems/activesupport-5.2.2/lib/active_support/dependencies.rb:285:in `load'
/usr/local/bundle/gems/railties-5.2.2/lib/rails/engine.rb:551:in `load_seed'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/tasks/database_tasks.rb:281:in `load_seed'
/usr/local/bundle/gems/activerecord-5.2.2/lib/active_record/railties/databases.rake:194:in `block (2 levels) in <main>'
/usr/local/bundle/gems/rake-12.3.2/exe/rake:27:in `<top (required)>'
Tasks: TOP => db:seed
(See full trace by running task with --trace)

我尝试使用User.where([{*same_value*}]).first_or_create,但仍然遇到相同的错误。

这是user.rb模型

class User < ApplicationRecord

  serialize :groups
  validates :groups, presence: true

  devise :database_authenticatable, :rememberable, :trackable, :validatable,
    :omniauthable, omniauth_providers: [:google_oauth2]

  scope :admins, -> { where('groups LIKE ?', "%#{User::ADMIN}%") }

  ADMIN = 'admin'
  ROOT = 'root'
  DEV = 'dev'
  BO = 'bo'
  AFFILIATE = 'affiliate'

  def manageable_groups
    if root?
      [ROOT, ADMIN, BO, DEV, AFFILIATE]
    elsif admin?
      [ADMIN, BO, DEV, AFFILIATE]
    else
      []
    end
  end

  def formatted_slack_user_or_first_name
    formatted_slack_user || first_name
  end

  def formatted_slack_user
    "<@#{self.slack_user}>" unless self.slack_user.nil?
  end

  def first_name
    self.name.split(' ').first
  end

  def admin?
    self.groups[:role] == User::ADMIN
  end

  def affiliate?
    self.groups[:role] == User::AFFILIATE
  end

  def root?
    self.groups[:role] == User::ROOT
  end

  def dev?
    self.groups[:role] == User::DEV
  end

  def bo?
    self.groups[:role] == User::BO
  end

  def self.from_omniauth(access_token)
      data = access_token.info
      user = User.where(email: data['email'].downcase).first

      unless user
          user = User.create(name: data['name'],
            email: data['email'].downcase,
            groups: {role: User::BO, countries: :all},
            password: Devise.friendly_token[0,20]
          )
      end
      user
  end

  def permitted_gateways
    groups[:gateways]
  end

  def permitted_countries
    groups[:countries]
  end
end

有人可以帮我吗?谢谢!

1 个答案:

答案 0 :(得分:2)

User.find_or_create_by需要属性而不是数组,请使用下一种格式:

[
  { name: 'Root', email: 'root@sam-media.com', groups: {role: 'root', countries: :all}, password: 'asdfasdf' },
  { name: 'Admin', email: 'admin@sam-media.com', groups: {role: 'admin', countries: :all}, password: 'asdfasdf' },
  { name: 'Dev', email: 'dev@sam-media.com', groups: {role: 'dev', countries: :all}, password: 'asdfasdf' },
  { name: 'BO', email: 'bo@sam-media.com', groups: {role: 'root', countries: :all}, password: 'asdfasdf' },
  { name: 'Affiliate', email: 'uk@sam-media.com', groups: {role: 'affiliate', countries: 'uk', gateways: ['Oxygen8']}, password: 'asdfasdf' }
].each do |attributes|
  User.find_or_create_by(attributes)
end