Старая ошибка Ruby повторяется в моем приложении Ruby on Rails, связанная с Class.create и delayed_job

#ruby-on-rails #ruby #delayed-job

#ruby-on-rails #ruby #отложенное задание

Вопрос:

Ошибке много месяцев, здесь:

http://www.ruby-forum.com/topic/1094002

Две ссылки в том, что показывает изменения кода:

https://github.com/godfat/ruby/commit/f4e0e8f781b05c767ad2472a43a4ed0727a75708
https://github.com/godfat/ruby/commit/c7a6cf975d88828c2ed27d253f41c480f9b66ad6

У меня Ruby 1.9.2 и rvm. Я бы вставил эти изменения в соответствующие файлы, но я не знаю как.

Это сработало несколько дней назад. Я не могу выполнять команды Ruby on Rails, такие как:

 >> User.create :username => "a", :password => "a"
  

Вот сообщение об ошибке:

 ArgumentError: wrong number of arguments(1 for 0)
from /Users/RedApple/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:48:in `method'
from /Users/RedApple/.rvm/rubies/ruby-1.9.2 p290/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:48:in `accept'
from /Users/RedApple/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/visitors/yaml_tree.rb:36:in `<<'
from /Users/RedApple/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych.rb:165:in `dump'
from /Users/RedApple/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/psych/core_ext.rb:13:in `psych_to_yaml'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/delayed_job-2.0.4/lib/delayed/backend/base.rb:57:in `payload_object='
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:2918:in `block in assign_attributes'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:2914:in `each'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:2914:in `assign_attributes'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:2787:in `attributes='
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:2477:in `initialize'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:725:in `new'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:725:in `create'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/delayed_job-2.0.4/lib/delayed/message_sending.rb:9:in `method_missing'
from /Users/RedApple/S/app/models/user.rb:29:in `block in <class:User>'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-2.3.14/lib/active_support/callbacks.rb:182:in `call'
... 7 levels...
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/callbacks.rb:267:in `create_with_callbacks'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:2927:in `create_or_update'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/callbacks.rb:250:in `create_or_update_with_callbacks'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:2577:in `save'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/validations.rb:1089:in `save_with_validation'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/dirty.rb:79:in `save_with_dirty'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/transactions.rb:229:in `block in with_transaction_returning_status'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/transactions.rb:182:in `transaction'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/transactions.rb:228:in `with_transaction_returning_status'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/transactions.rb:196:in `block in save_with_transactions'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/transactions.rb:196:in `save_with_transactions'
from /Users/RedApple/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-2.3.14/lib/active_record/base.rb:727:in `create'
from (irb):1
from /Users/RedApple/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'>
  

Строка 28-30 в user.rb:

 after_create do |user|
  user.delay( :priority => -15 ).seed
end
  

Я мертв в воде без этого. Кто-нибудь может помочь?

Комментарии:

1. Обновление: я перешел на использование Ruby 1.8.7, и это больше не проблема, что означает, что это явно ошибка Ruby 1.9.2. Мне все равно хотелось бы найти решение, поскольку лучше всего использовать одну и ту же среду при разработке и производстве.

2. Обновление: несмотря на то, что он работает в 1.8.7, у меня возникают другие проблемы с 1.8.7, поэтому мне действительно нужно, чтобы он работал в 1.9.2.

Ответ №1:

К сожалению, отложенное задание и анализатор Ruby 1.9.2 YAML (Psych) несовместимы.

Вернитесь к предыдущему синтаксическому анализатору YAML (Syck), добавив это в свой config/application.rb , чуть ниже вызова Bundler.require :

 YAML::ENGINE.yamler = "syck" if RUBY_VERSION >= "1.9.2"
  

Комментарии:

1. Большое спасибо. На самом деле я вставил его в config/environment.rb. Теперь это работает.

2. Мне это не кажется хорошим решением. Все документы указывают на то, что Psych сейчас является предпочтительным бэкэндом YAML.

3. @simianarmy, все это очень хорошо, но пока отложенная работа не будет исправлена, другого пути нет.

4. Конечно, есть — вам просто нужно позволить Psych работать с данными с помощью:ключи метода в них — см. Расширение в ответе ниже.

Ответ №2:

Вы могли бы исправить свой Ruby, но это непросто и на самом деле невозможно на управляемых хостах. Моим решением было создать monkeypatch на основе фиксации исправления 31075.

Создайте файл инициализатора в вашем проекте Rails config/initializers/psych_extensions.rb и добавьте этот код:

 # APPLIES RUBY PATCH REVISION 31075

module Psych
  module Visitors
    ###
    # YAMLTree builds a YAML ast given a ruby object.  For example:
    #
    #   builder = Psych::Visitors::YAMLTree.new
    #   builder << { :foo => 'bar' }
    #   builder.tree # => #<Psych::Nodes::Stream .. }
    #
    class YAMLTree < Psych::Visitors::Visitor

      def accept target
        # return any aliases we find
        if node = @st[target.object_id]
          node.anchor = target.object_id.to_s
          return @emitter.alias target.object_id.to_s
        end

        if target.respond_to?(:to_yaml)
          loc = target.public_method(:to_yaml).source_location.first
          if loc !~ /(syck/rubytypes.rb|psych/core_ext.rb)/
            unless target.respond_to?(:encode_with)
              if $VERBOSE
                warn "implementing to_yaml is deprecated, please implement "encode_with""
              end

              target.to_yaml(:nodump => true)
            end
          end
        end

        if target.respond_to?(:encode_with)
          dump_coder target
        else
          send(@dispatch_cache[target.class], target)
        end
      end

      private

      # FIXME: remove this method once "to_yaml_properties" is removed
      def find_ivars target
        loc = target.public_method(:to_yaml_properties).source_location.first
        unless loc.start_with?(Psych::DEPRECATED) || loc.end_with?('rubytypes.rb')
          if $VERBOSE
            warn "#{loc}: to_yaml_properties is deprecated, please implement "encode_with(coder)""
          end
          return target.to_yaml_properties
        end

        target.instance_variables
      end

    end
  end
end