2011-12-24 1 views
2

Я создаю приложение sinatra, которое будет использовать драгоценный камень Highrise CRM для доступа к данным Highrise. Этот камень основан на классе ActiveResource. Я хочу установить сайт, поля пользователя для каждого запроса. Я следовал за предложением, размещенным здесь - Is it thread safe to set Active Resource HTTP authentication on a per-user basis?. Я добавляю код (показано ниже), и я получаю сообщение об ошибке. Может кто-нибудь помочь понять эту ошибку и как ее исправить.Установить поля сайта/пользователя в ActiveResource

class ActiveResource::Base 
    class << self 
    %w(site user).each do |attr|    

     define_method(attr) do 
     Thread.current["active_resource.#{attr}"] 
     end 

     define_method("#{attr}=", val) do 
     Thread.current["active_resource.#{attr}"] = val 
     end 
    end 
    end 
end 

И ошибка:

c:/dev/hgadget/application.rb:18:in `block in singletonclass': 
undefined local variable or method `val' for #<Class:ActiveResource::Base> (NameError) 
    from c:/dev/hgadget/application.rb:12:in `each' 
    from c:/dev/hgadget/application.rb:12:in `singletonclass' 
    from c:/dev/hgadget/application.rb:11:in `<class:Base>' 
    from c:/dev/hgadget/application.rb:9:in `<top (required)>' 
    from <internal:lib/rubygems/custom_require>:29:in `require' 
    from <internal:lib/rubygems/custom_require>:29:in `require' 
    from application_test.rb:1:in `<main>' 

------------------------ обновление ------- ----------------------

Я попробовал ваше предложение, теперь я получаю эту ошибку.

NoMethodError - undefined method `path' for "https://test.abcd.com":String: 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/activeresource3.0.11/lib/active_resource/base.rb:562:in `prefix' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/activeresource3.0.11/lib/active_resource/base.rb:667:in `collection_path' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/activeresource3.0.11/lib/active_resource/base.rb:856:in `find_every' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/activeresource-3.0.11/lib/active_resource/base.rb:777:in `find' application.rb:78:in `block in <main>' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.3.1/lib/sinatra/base.rb:1212:in `call' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.3.1/lib/sinatra/base.rb:1212:in `block in compile!' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.3.1/lib/sinatra/base.rb:772:in `[]' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.3.1/lib/sinatra/base.rb:772:in `block (3 levels) in route!' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.3.1/lib/sinatra/base.rb:788:in `route_eval' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.3.1/lib/sinatra/base.rb:772:in `block (2 levels) in route!' 
    c:/Ruby192/lib/ruby/gems/1.9.1/gems/sinatra-1.3.1/lib/sinatra/base.rb:821:in `block in process_route' 

ответ

0

Хотя метод определения с define_method вы можете указать его аргументы передать их в качестве аргументов блока и не define_method сам. Таким образом, вы можете определить сеттер метод так:

define_method("#{attr}=") do |val| 
    Thread.current["active_resource.#{attr}"] = val 
end 
+0

Я попробовал то, что вы сказали, я получаю сообщение об ошибке - «NoMethodError - неопределенный метод' путь»для„https://abcd.test.com“: Строка:» – user1112996

1

Я играл много с установкой site опции динамически во время выполнения, и единственным решением я нашел, не приведет к гонке условия.

class Runner 
    def self.new(site) 
    Class.new(ActiveResource::Base) do 
     self.site = site 
     self.element_name = 'runner' 

     # your methods here 
    end.new 
    end 
end 
+0

Я пытаюсь создать форма для объектов из этого анонимного класса, но анонимные классы не работают с ActiveModel, ни с формами. Я получаю: 'Имя класса не может быть пустым. Вам нужно указать аргумент имени, если указан анонимный класс. Вы нашли решение этой проблемы? Благодарю. – dombesz

+0

Это не мой случай использования, я использую его только из внутреннего кода для извлечения и отправки пользовательских данных, даже не следуя спецификациям REST, поэтому я не знаю, как он будет работать в стандартном рабочем процессе. Но я тоже не доволен этим обходным решением. – troex