Git Product home page Git Product logo

kano's People

Contributors

hymredemption avatar nobrick avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

kano's Issues

Rename .css.scss to .scss

@hymRedemption assets 目录里面有不少 .css.scss 文件,好像现在这种命名方式已经过时,日志中会出现警告:

DEPRECATION WARNING: Extra .css in SCSS file is unnecessary. Rename /Users/tornado/my_rails/kano/app/assets/stylesheets/admin/block/profile.css.scss to /Users/tornado/my_rails/kano/app/assets/stylesheets/admin/block/profile.scss. (called from _app_views_layouts_admin_html_slim__2218613434358692054_70126129660040 at /Users/tornado/my_rails/kano/app/views/layouts/admin.html.slim:4)

提现申请限制问题

@nobrick 现在提现申请的限制好像只是让 index 页面根据当前状态提供相应的页面显示。但对于 create 方法来说,没有再次对这些限制进行检查。

这样很可能出现问题。
首先,提现申请的限制之一是: 只能有一个提现正在进行。如果师傅在申请提现之前,同时开启两个申请提现的页面,然后两次进行提交。这样就能够越过我们的限制。这样也让财务信息出现错误。因为师傅实际最大可以提现出“可提现金额”的两倍。

另一个问题就是,用户只要保留住提现申请的页面。就可以不用在我们限定的提现日提现。他可以随便在那天进行提现。

ransack 高级搜索

问题现象

2016-02-24 11 12 52

描述:每次我设置条件搜索之后,返回页面的时候,其 helper 会保留之前搜索使用的条件,然后再建立一个新的等待用户输入的条件框。 但我只想保留一个条件设置框。我和 ransack 的事例 demo 比较,发现实现没有差别,但是现实就有问题。 ### 代码 - 前端
= search_form_for @search, url: url_path, method: :post do |f|
    = f.condition_fields nil do |c|
      = c.attribute_fields do |a|
        = a.attribute_select
      = c.predicate_select
      = c.value_fields do |v|
        = v.text_field :value, class: "form-control"
    .input-group-btn
      = f.submit '搜索', class: 'btn btn-default'
  • 后端
  def index
    @search = Taxon.ransack(params[:q])
    @taxons = @search.result.includes(:handyman).order(cert_requested_at: :desc)

    @taxons = @taxons.page(params[:page]).per(10)
    @search.build_condition
  end

 #高级搜索指向改方法
  def search
     index
     render 'index'
  end

延迟注册问题

现有延迟注册

现在延迟注册的时候,用户只提供 email 和 password 就能注册了, phone 可以是空。

有问题的地方

但是 phone 在数据库层面做了 unique,而在数据库中,两个 phone 属性都为空字符(不是 null)的数据,数据库认为是违反了 unique(虽然在 Model 中 allow_blank)。

问题现象重复方式: 通过网页注册两个都不提供 phone 属性的账号。在第一个账号不完善资料的情况下,注册第二个账号,数据库会报错

可行的解决方式

相对简单的解决办法是,后台确保 phone 为空的时候,其值应为 nil

重发订单

取消订单后重定向至 预约订单 页面,并自动填写好 订单内容、维修项目 等相关参数,支持用户修改后下单。

师傅头像支持

@wangxiran: 第六就是希望能否加入师傅头像的功能,师傅接单后,用户支付页面也加入师傅的头像,方便用户判断是否为大象管家师傅。因为很多用户还是有很大的安全担忧。

师傅维修服务认证

Taxon模型中可以考虑增加下面几项属性:

  • certified_status,认证过程的三种状态
  • cert_requested_at,(最新的)申请认证时间
  • certified_at,(最新的)审核认证时间
  • certified_by,认证人,通常为admin身份的user
  • reason_code,(最近一次的)认证失败的类型代码,例如资料不全对应'missing_info'等,便于扩展
  • reason_message,(最近一次的)认证失败的附加文字消息,可为空

管理后台

逻辑:对于指定师傅,显示每一项维修服务的状态,对于“申请中”的维修项目,提供“认证技能”按钮和“拒绝申请”功能。前者通过该项技能认证,后者设置技能认证“未通过”状态,并提供认证失败类型代码(reason_code)以及附加原因(reason_message)。

前提:必须以admin身份登录后台。

师傅前端

逻辑有待补充。

See https://github.com/nobrick/kano/wiki/Requirements-1.0#师傅技能维修服务认证

about coding

@hymRedemption 我看了最近的 PR 以后,觉得实现得非常好,但是也觉得在方法上可能存在一些问题,这里主要说说我自己的个人看法:

PR 和 git branch、commit 的粒度过大

一个 PR 或者 branch 里面包含了过多的不相关内容,不利于快速跟进代码变化,也给 code review 带来比较大的困难。而每个 commit 的粒度过大首先会导致实际 commit 的内容很可能与 commit message 的描述有较大差异,增加协作时的理解难度,其次会导致 commit 和 push 的频率很低,比如仅在提交 PR 时 commit,所有的讨论也只能在 PR 提交的时候才进行,这也非常不利于交流。

对于个人项目来说,随意使用 Git 甚至不用版本控制工具(使用 Time machine 来取代)都是完全合理的。但 VCS 对于多人协作来说,是很有必要的,给 merge 带来很大便利的 Git 更是如此:频繁的 Git 操作虽然在一定程度上增加了开发时间开销,尤其最初也许会不习惯,更加分散注意力,但逐渐习惯、熟练以后,其实会带来很大的好处,不仅仅是更有利于协作(疑问可以及时得到解答,潜在 issue 也许可以避免),其实也是一种自己管理代码的有效方式,比如我习惯随时执行 git diff,执行的频率差不多接近 TDD 的频率,可以比较好地回顾自己的代码变动,如果一直追求 better way to code,这可能是一种方法。

commit 的代码不见得就一定要保证完全正确的,我的理解它只是代表做了一件事情,哪怕仅仅是一个单纯的 migration 这样的小事。这样保证了 commit 的原子性,一个 commit 有独立的目的,不夹杂过多的“私货”,才能不致于把所有的代码变化全都 commit 到一个 branch 上面去,这样产品本身也可以按照功能快速迭代,而且随时比较 commit diff 也有利于提高代码质量。

测试过少,重构困难

Ruby 作为一个 duck typing 的语言,灵活度很高,但是在我看来也非常容易出错,尤其是在重构的时候,看起来利索无比的代码,可能一不小心就输出错误或者抛出异常了。所以测试是保持程序正确性、稳健性的重要手段,就我所知,是目前可以保证重构尽可能正确的最有效方法。

仅依赖于 seeds 在 dev 环境产生数据进行人工验证,首先在软件复杂度、业务逻辑不断上升的情况下,人工验证的成本也越来越高(虽然也很有必要),而且如果 seeds 本身没有模拟足够“真实”的数据,这种数据不一致带来差异也会带来一些问题(比如出现 exception,而且是在 dev 环境下无法利用测试检验)。

这个问题其实也不用多少了,看看 Ruby 的各个开源代码项目就知道了,即便 DHH 不赞成 TDD,他也说了 long live tests,Basecamp 的 repo 测试率也达到了 0.6 以上。

命名和组织结构不够规范

哲学家这么说:

There are only two hard things in Computer Science: cache invalidation and naming things.

所以命名确实是一个很困难的问题,我也经常遇到想不好该如何命名某个 object 、该怎么组织代码。但我确实觉得命名非常重要,都说好的代码是自明的,虽然做到这一点确实很难,但重视以后就可以更好地改进:比如我一开始不清楚电商系统的一些状态的命名,所以就多去参考一些相关的开源项目,学习他们的命名方式和代码结构。再比如,如果名称上面建立了两个对立的方法,那么他们的行为也应该尽可能地对立,不应该产生一些与直觉不符的行为。

我觉得其实这个问题也和前面两个问题有比较大的关联,如果快速提交小而美的 commit、PR,在多人协作的环境下,大家可以集思广益更好地商讨命名问题,我觉得这可能也是开源的思维方式:Rails 在 Github 上经常讨论一个方法的 signature 应该如何设计。当然咱们并不是做 API 和框架,并不需要那样细致,但至少一起考虑名称的合理性有利于代码的可读和维护;另一方面重新命名其实非常普遍,而且对 Ruby 来说并不像 Java 那样自动化,也完全可以算作一个重构了,因此测试对于重命名也很重要,也许会减少因为“仅仅重新改了方法名和几乎所有的引用但是仍然出现exception”的尴尬了。

管家接单功能的并行问题

目前,订单接单功能目前处理并行抢单好像并不太好。

现在抢单功能的正确性应该能够保证,因为 save 本身是一个事务, 所以就算有两个师傅同时抢单的时候,也会因为 save 是事务,而使一个师傅因为状态改变不对而抢单失败。

但是这样的实现会因为在 save 过程中抛错而使某个师傅接收到 500 的页面,这样是不是不太友好。

我的想法是将目前 filter 中的 check_order_permission 和 save 相关逻辑放到一个事务中,这样就能提供好一些的反馈。
@nobrick

通过师傅技能认证时抛出异常

@hymRedemption account-management branch 中关于师傅技能认证的需求是否已经可以满足正常运行,还是因为什么原因已经 broken?

我在点击“通过”认证时,提示异常:

ArgumentError at /alpha/handymen/certifications/43
wrong number of arguments (1 for 3)
Request parameters  

{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}

Rack session    

#<ActionDispatch::Request::Session:0x007fa0e0e81858 @by=#<ActionDispatch::Session::CookieStore:0x007fa0e2006808 @app=#<ActionDispatch::Flash:0x007fa0e2006830 @app=#<ActionDispatch::ParamsParser:0x007fa0e20068f8 @app=#<Rack::Head:0x007fa0e2006920 @app=#<Rack::ConditionalGet:0x007fa0e2006948 @app=#<Rack::ETag:0x007fa0e2006998 @app=#<Warden::Manager:0x007fa0e2006a60 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, @app=#<OmniAuth::Strategies::Wechat>>, @cache_control="max-age=0, private, must-revalidate", @no_cache_control="no-cache">>>, @parsers={#<Mime::Type:0x007fa0dcd90128 @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json, @string="application/json">=>:json}>>, @default_options={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false}, @key="_kano_session", @cookie_only=true>, @env={"CONTENT_LENGTH"=>"212", "CONTENT_TYPE"=>"application/x-www-form-urlencoded", "GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/alpha/handymen/certifications/43", "QUERY_STRING"=>"", "REMOTE_ADDR"=>"127.0.0.1", "REMOTE_HOST"=>"127.0.0.1", "REQUEST_METHOD"=>"PUT", "REQUEST_URI"=>"http://localhost:3000/alpha/handymen/certifications/43", "SCRIPT_NAME"=>"", "SERVER_NAME"=>"localhost", "SERVER_PORT"=>"3000", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/2.2.3/2015-08-18)", "HTTP_HOST"=>"localhost:3000", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0", "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.7,zh;q=0.3", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_REFERER"=>"http://localhost:3000/alpha/handymen/certifications", "HTTP_COOKIE"=>"_kano_session=NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ%3D%3D--8f7965a0d911d61a0be76c2c7806ac61eacad543", "HTTP_CONNECTION"=>"keep-alive", "rack.version"=>[1, 3], "rack.input"=>#<StringIO:0x007fa0e0f63550>, "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "rack.url_scheme"=>"http", "rack.hijack?"=>true, "rack.hijack"=>#<Proc:0x007fa0e0f63438@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb:76 (lambda)>, "rack.hijack_io"=>nil, "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_PATH"=>"/alpha/handymen/certifications/43", "ORIGINAL_FULLPATH"=>"/alpha/handymen/certifications/43", "ORIGINAL_SCRIPT_NAME"=>"", "action_dispatch.routes"=>#<ActionDispatch::Routing::RouteSet:0x007fa0dc1ddd58>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.redirect_filter"=>[], "action_dispatch.secret_token"=>nil, "action_dispatch.secret_key_base"=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", "action_dispatch.show_exceptions"=>true, "action_dispatch.show_detailed_exceptions"=>true, "action_dispatch.logger"=>#<ActiveSupport::Logger:0x007fa0e2433d40 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x007fa0e2433cc8 @datetime_format=nil>, @formatter=#<ActiveSupport::Logger::SimpleFormatter:0x007fa0e0e4f308 @datetime_format=nil>, @logdev=#<Logger::LogDevice:0x007fa0e2433c78 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<File:/Users/tornado/my_rails/kano/log/development.log>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x007fa0e2433c50 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fa0e2433c00>>>>, "action_dispatch.backtrace_cleaner"=>#<Rails::BacktraceCleaner:0x007fa0e0f32e78 @filters=[#<Proc:0x007fa0e0f32d60@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:14>, #<Proc:0x007fa0e0f32d38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:15>, #<Proc:0x007fa0e0f32d10@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:16>, #<Proc:0x007fa0e0f32928@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:29>], @silencers=[#<Proc:0x007fa0e0f32900@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:19>], @root="/Users/tornado/my_rails/kano/">, "action_dispatch.key_generator"=>#<ActiveSupport::CachingKeyGenerator:0x007fa0e06e05b8 @key_generator=#<ActiveSupport::KeyGenerator:0x007fa0e06e05e0 @secret="c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", @iterations=1000>, @cache_keys=#<ThreadSafe::Cache:0x007fa0e06e0590 @backend={"signed_global_ids64"=>"\f\xC4\xC4\xFC#\xA1\x90V\xA0-4\xC2\xF4Q\xE6\xB4\xE7\xD0\x96\xF8t\xBA\\\xAA7\xC3\xBD\x1Aq\xB4O\xFBv\x02I*W\xCA\xB7\xB1U\x9E\xE4\x96\xBD\xFD^O\x8AC)\xDC\xF6\xA2p\xC25\x81\xC0\xC2\xCBH\xE5w", "encrypted cookie64"=>"\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", "signed encrypted cookie64"=>"\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C"}, @default_proc=nil>>, "action_dispatch.http_auth_salt"=>"http authentication", "action_dispatch.signed_cookie_salt"=>"signed cookie", "action_dispatch.encrypted_cookie_salt"=>"encrypted cookie", "action_dispatch.encrypted_signed_cookie_salt"=>"signed encrypted cookie", "action_dispatch.cookies_serializer"=>:json, "action_dispatch.cookies_digest"=>nil, "ROUTES_70164432219820_SCRIPT_NAME"=>"", "rack.request.form_hash"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过"}, "rack.request.form_vars"=>"utf8=%E2%9C%93&_method=put&authenticity_token=Cbx%2BHG%2Fv5rekgp0s3toD5xW39%2Fs8Z6LJXng1ez5mdQbOvQa%2B%2B5RHWA24bYrjPulLVh%2Fok19H2JwGyFkYEPl51Q%3D%3D&taxon%5Bcertified_status%5D=success&commit=%E9%80%9A%E8%BF%87", "rack.request.form_input"=>#<StringIO:0x007fa0e0f63550>, "rack.methodoverride.original_method"=>"POST", "action_dispatch.request_id"=>"b9a49b46-c019-4f73-8541-040c404b0513", "action_dispatch.remote_ip"=>#<ActionDispatch::RemoteIp::GetIp:0x007fa0e23f8970 @env={...}, @check_ip=true, @proxies=[#<IPAddr: IPv4:127.0.0.1/255.255.255.255>, #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, #<IPAddr: IPv6:fc00:0000:0000:0000:0000:0000:0000:0000/fe00:0000:0000:0000:0000:0000:0000:0000>, #<IPAddr: IPv4:10.0.0.0/255.0.0.0>, #<IPAddr: IPv4:172.16.0.0/255.240.0.0>, #<IPAddr: IPv4:192.168.0.0/255.255.0.0>]>, "rack.session"=>#<ActionDispatch::Request::Session:0x007fa0e0e81858 ...>, "rack.session.options"=>#<ActionDispatch::Request::Session::Options:0x007fa0e0e81808 @by=#<ActionDispatch::Session::CookieStore:0x007fa0e2006808 @app=#<ActionDispatch::Flash:0x007fa0e2006830 @app=#<ActionDispatch::ParamsParser:0x007fa0e20068f8 @app=#<Rack::Head:0x007fa0e2006920 @app=#<Rack::ConditionalGet:0x007fa0e2006948 @app=#<Rack::ETag:0x007fa0e2006998 @app=#<Warden::Manager:0x007fa0e2006a60 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, @app=#<OmniAuth::Strategies::Wechat>>, @cache_control="max-age=0, private, must-revalidate", @no_cache_control="no-cache">>>, @parsers={#<Mime::Type:0x007fa0dcd90128 @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json, @string="application/json">=>:json}>>, @default_options={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false}, @key="_kano_session", @cookie_only=true>, @env={...}, @delegate={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false, :id=>"17ef4264a6ad06cc7e2e31ce218e632d"}>, "action_dispatch.request.content_type"=>#<Mime::Type:0x007fa0dcd90420 @synonyms=[], @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded">, "warden"=>Warden::Proxy:70164472400600 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, "action_dispatch.request.path_parameters"=>{:controller=>"admin/handymen/certifications", :action=>"update", :id=>"43"}, "rack.request.cookie_hash"=>{"_kano_session"=>"NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ==--8f7965a0d911d61a0be76c2c7806ac61eacad543"}, "rack.request.cookie_string"=>"_kano_session=NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ%3D%3D--8f7965a0d911d61a0be76c2c7806ac61eacad543", "action_dispatch.cookies"=>#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 @key_generator=#<ActiveSupport::CachingKeyGenerator:0x007fa0e06e05b8 @key_generator=#<ActiveSupport::KeyGenerator:0x007fa0e06e05e0 @secret="c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", @iterations=1000>, @cache_keys=#<ThreadSafe::Cache:0x007fa0e06e0590 @backend={"signed_global_ids64"=>"\f\xC4\xC4\xFC#\xA1\x90V\xA0-4\xC2\xF4Q\xE6\xB4\xE7\xD0\x96\xF8t\xBA\\\xAA7\xC3\xBD\x1Aq\xB4O\xFBv\x02I*W\xCA\xB7\xB1U\x9E\xE4\x96\xBD\xFD^O\x8AC)\xDC\xF6\xA2p\xC25\x81\xC0\xC2\xCBH\xE5w", "encrypted cookie64"=>"\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", "signed encrypted cookie64"=>"\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C"}, @default_proc=nil>>, @set_cookies={"request_method"=>{:value=>"PUT", :path=>"/"}}, @delete_cookies={}, @host="localhost", @secure=false, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @cookies={"_kano_session"=>"NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ==--8f7965a0d911d61a0be76c2c7806ac61eacad543", "request_method"=>"PUT"}, @committed=false, @encrypted=#<ActionDispatch::Cookies::EncryptedCookieJar:0x007fa0e2202940 @parent_jar=#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 ...>, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @encryptor=#<ActiveSupport::MessageEncryptor:0x007fa0dd9ffcb0 @secret="\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", @sign_secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007fa0dd9ffbe8 @secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=ActiveSupport::MessageEncryptor::NullSerializer>>, @signed_or_encrypted=#<ActionDispatch::Cookies::EncryptedCookieJar:0x007fa0e2202940 @parent_jar=#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 ...>, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @encryptor=#<ActiveSupport::MessageEncryptor:0x007fa0dd9ffcb0 @secret="\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", @sign_secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007fa0dd9ffbe8 @secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=ActiveSupport::MessageEncryptor::NullSerializer>>>, "action_dispatch.request.unsigned_session_cookie"=>{"session_id"=>"17ef4264a6ad06cc7e2e31ce218e632d", "warden.user.account.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "warden.user.user.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "_csrf_token"=>"xwF4opR7oe+pOvCmPeTqrEOoH2hjIHpVWLBsYy6fDNM="}, "action_controller.instance"=>#<Admin::Handymen::CertificationsController:0x007fa0e0a574f8 @_action_has_layout=true, @_routes=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=#<ActionDispatch::Request:0x007fa0e0a573b8 @env={...}, @filtered_parameters={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, @filtered_env=nil, @filtered_path=nil, @protocol=nil, @port=nil, @method=nil, @request_method="PUT", @remote_ip=nil, @original_fullpath=nil, @fullpath="/alpha/handymen/certifications/43", @ip=nil, @uuid=nil>, @_response=#<ActionDispatch::Response:0x007fa0e0a57368 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fa0e0a57278>, @stream=#<ActionDispatch::Response::Buffer:0x007fa0e0a571b0 @response=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @buf=[], @closed=false>, @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff"}, @status=200, @sending_file=false, @blank=false, @cv=#<MonitorMixin::ConditionVariable:0x007fa0e0a57188 @monitor=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @cond=#<Thread::ConditionVariable:0x007fa0e0a57160>>, @committed=false, @sending=false, @sent=false, @content_type=nil, @charset=nil, @cache_control={}, @etag=nil, @request=#<ActionDispatch::Request:0x007fa0e0a573b8 @env={...}, @filtered_parameters={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, @filtered_env=nil, @filtered_path=nil, @protocol=nil, @port=nil, @method=nil, @request_method="PUT", @remote_ip=nil, @original_fullpath=nil, @fullpath="/alpha/handymen/certifications/43", @ip=nil, @uuid=nil>>, @_env={...}, @_lookup_context=#<ActionView::LookupContext:0x007fa0e0a56d78 @details_key=nil, @details={:locale=>[:"zh-CN"], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :slim, :jbuilder]}, @skip_default_locale=false, @cache=true, @prefixes=["admin/handymen/certifications", "admin/application"], @rendered_format=nil, @view_paths=#<ActionView::PathSet:0x007fa0e0a56cb0 @paths=[#<ActionView::OptimizedFileSystemResolver:0x007fa0e2400f08 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2400ee0 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2400eb8 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/my_rails/kano/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2401660 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2401638 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2401610 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/kaminari-0.16.3/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e24028a8 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2402880 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2402858 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/china_city-0.0.4/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2403410 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e24033e8 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e24033c0 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/devise-3.4.1/app/views">]>>, @_action_name="update", @_response_body=nil, @__react_component_helper=#<React::Rails::ComponentMount:0x007fa0e0a376f8>, @current_user=#<User id: 1, email: "[email protected]", encrypted_password: "$2a$10$L6eoo/WZILLlZewSK0R8g.6ay09W1mH0y3blmsg/kFy...", phone: "13107485756", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 166, current_sign_in_at: "2016-01-24 14:04:28", last_sign_in_at: "2016-01-24 14:04:28", current_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, last_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, admin: true, coins: 0, name: "曲先生", provider: "wechat", uid: "abcde", nickname: "", gender: nil, wechat_headimgurl: nil, created_at: "2015-10-23 12:09:35", updated_at: "2016-01-24 14:04:28", type: "User", primary_address_id: 1>, @_params={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}>, "action_dispatch.request.request_parameters"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过"}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, "action_dispatch.request.formats"=>[#<Mime::Type:0x007fa0dcd99f98 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">]}, @delegate={"session_id"=>"17ef4264a6ad06cc7e2e31ce218e632d", "warden.user.account.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "warden.user.user.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "_csrf_token"=>"xwF4opR7oe+pOvCmPeTqrEOoH2hjIHpVWLBsYy6fDNM="}, @loaded=true, @exists=true>

Local Variables
taxon   

#<Taxon id: 43, handyman_id: 3, code: "water/other", created_at: "2015-11-25 17:22:16", updated_at: "2015-11-25 17:22:16", certified_status: "under_review", cert_requested_at: nil, certified_at: nil, certified_by: nil, reason_code: nil, reason_message: nil>

certified_attrs 

nil

Instance Variables
@_action_has_layout 

true

@_routes    

nil

@_headers   

{"Content-Type"=>"text/html"}

@_status    

200

@_request   

#<ActionDispatch::Request:0x007fa0e0a573b8 @env={"CONTENT_LENGTH"=>"212", "CONTENT_TYPE"=>"application/x-www-form-urlencoded", "GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/alpha/handymen/certifications/43", "QUERY_STRING"=>"", "REMOTE_ADDR"=>"127.0.0.1", "REMOTE_HOST"=>"127.0.0.1", "REQUEST_METHOD"=>"PUT", "REQUEST_URI"=>"http://localhost:3000/alpha/handymen/certifications/43", "SCRIPT_NAME"=>"", "SERVER_NAME"=>"localhost", "SERVER_PORT"=>"3000", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/2.2.3/2015-08-18)", "HTTP_HOST"=>"localhost:3000", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0", "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.7,zh;q=0.3", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_REFERER"=>"http://localhost:3000/alpha/handymen/certifications", "HTTP_COOKIE"=>"_kano_session=NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ%3D%3D--8f7965a0d911d61a0be76c2c7806ac61eacad543", "HTTP_CONNECTION"=>"keep-alive", "rack.version"=>[1, 3], "rack.input"=>#<StringIO:0x007fa0e0f63550>, "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "rack.url_scheme"=>"http", "rack.hijack?"=>true, "rack.hijack"=>#<Proc:0x007fa0e0f63438@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb:76 (lambda)>, "rack.hijack_io"=>nil, "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_PATH"=>"/alpha/handymen/certifications/43", "ORIGINAL_FULLPATH"=>"/alpha/handymen/certifications/43", "ORIGINAL_SCRIPT_NAME"=>"", "action_dispatch.routes"=>#<ActionDispatch::Routing::RouteSet:0x007fa0dc1ddd58>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.redirect_filter"=>[], "action_dispatch.secret_token"=>nil, "action_dispatch.secret_key_base"=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", "action_dispatch.show_exceptions"=>true, "action_dispatch.show_detailed_exceptions"=>true, "action_dispatch.logger"=>#<ActiveSupport::Logger:0x007fa0e2433d40 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x007fa0e2433cc8 @datetime_format=nil>, @formatter=#<ActiveSupport::Logger::SimpleFormatter:0x007fa0e0e4f308 @datetime_format=nil>, @logdev=#<Logger::LogDevice:0x007fa0e2433c78 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<File:/Users/tornado/my_rails/kano/log/development.log>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x007fa0e2433c50 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fa0e2433c00>>>>, "action_dispatch.backtrace_cleaner"=>#<Rails::BacktraceCleaner:0x007fa0e0f32e78 @filters=[#<Proc:0x007fa0e0f32d60@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:14>, #<Proc:0x007fa0e0f32d38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:15>, #<Proc:0x007fa0e0f32d10@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:16>, #<Proc:0x007fa0e0f32928@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:29>], @silencers=[#<Proc:0x007fa0e0f32900@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:19>], @root="/Users/tornado/my_rails/kano/">, "action_dispatch.key_generator"=>#<ActiveSupport::CachingKeyGenerator:0x007fa0e06e05b8 @key_generator=#<ActiveSupport::KeyGenerator:0x007fa0e06e05e0 @secret="c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", @iterations=1000>, @cache_keys=#<ThreadSafe::Cache:0x007fa0e06e0590 @backend={"signed_global_ids64"=>"\f\xC4\xC4\xFC#\xA1\x90V\xA0-4\xC2\xF4Q\xE6\xB4\xE7\xD0\x96\xF8t\xBA\\\xAA7\xC3\xBD\x1Aq\xB4O\xFBv\x02I*W\xCA\xB7\xB1U\x9E\xE4\x96\xBD\xFD^O\x8AC)\xDC\xF6\xA2p\xC25\x81\xC0\xC2\xCBH\xE5w", "encrypted cookie64"=>"\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", "signed encrypted cookie64"=>"\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C"}, @default_proc=nil>>, "action_dispatch.http_auth_salt"=>"http authentication", "action_dispatch.signed_cookie_salt"=>"signed cookie", "action_dispatch.encrypted_cookie_salt"=>"encrypted cookie", "action_dispatch.encrypted_signed_cookie_salt"=>"signed encrypted cookie", "action_dispatch.cookies_serializer"=>:json, "action_dispatch.cookies_digest"=>nil, "ROUTES_70164432219820_SCRIPT_NAME"=>"", "rack.request.form_hash"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过"}, "rack.request.form_vars"=>"utf8=%E2%9C%93&_method=put&authenticity_token=Cbx%2BHG%2Fv5rekgp0s3toD5xW39%2Fs8Z6LJXng1ez5mdQbOvQa%2B%2B5RHWA24bYrjPulLVh%2Fok19H2JwGyFkYEPl51Q%3D%3D&taxon%5Bcertified_status%5D=success&commit=%E9%80%9A%E8%BF%87", "rack.request.form_input"=>#<StringIO:0x007fa0e0f63550>, "rack.methodoverride.original_method"=>"POST", "action_dispatch.request_id"=>"b9a49b46-c019-4f73-8541-040c404b0513", "action_dispatch.remote_ip"=>#<ActionDispatch::RemoteIp::GetIp:0x007fa0e23f8970 @env={...}, @check_ip=true, @proxies=[#<IPAddr: IPv4:127.0.0.1/255.255.255.255>, #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, #<IPAddr: IPv6:fc00:0000:0000:0000:0000:0000:0000:0000/fe00:0000:0000:0000:0000:0000:0000:0000>, #<IPAddr: IPv4:10.0.0.0/255.0.0.0>, #<IPAddr: IPv4:172.16.0.0/255.240.0.0>, #<IPAddr: IPv4:192.168.0.0/255.255.0.0>]>, "rack.session"=>#<ActionDispatch::Request::Session:0x007fa0e0e81858 @by=#<ActionDispatch::Session::CookieStore:0x007fa0e2006808 @app=#<ActionDispatch::Flash:0x007fa0e2006830 @app=#<ActionDispatch::ParamsParser:0x007fa0e20068f8 @app=#<Rack::Head:0x007fa0e2006920 @app=#<Rack::ConditionalGet:0x007fa0e2006948 @app=#<Rack::ETag:0x007fa0e2006998 @app=#<Warden::Manager:0x007fa0e2006a60 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, @app=#<OmniAuth::Strategies::Wechat>>, @cache_control="max-age=0, private, must-revalidate", @no_cache_control="no-cache">>>, @parsers={#<Mime::Type:0x007fa0dcd90128 @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json, @string="application/json">=>:json}>>, @default_options={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false}, @key="_kano_session", @cookie_only=true>, @env={...}, @delegate={"session_id"=>"17ef4264a6ad06cc7e2e31ce218e632d", "warden.user.account.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "warden.user.user.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "_csrf_token"=>"xwF4opR7oe+pOvCmPeTqrEOoH2hjIHpVWLBsYy6fDNM="}, @loaded=true, @exists=true>, "rack.session.options"=>#<ActionDispatch::Request::Session::Options:0x007fa0e0e81808 @by=#<ActionDispatch::Session::CookieStore:0x007fa0e2006808 @app=#<ActionDispatch::Flash:0x007fa0e2006830 @app=#<ActionDispatch::ParamsParser:0x007fa0e20068f8 @app=#<Rack::Head:0x007fa0e2006920 @app=#<Rack::ConditionalGet:0x007fa0e2006948 @app=#<Rack::ETag:0x007fa0e2006998 @app=#<Warden::Manager:0x007fa0e2006a60 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, @app=#<OmniAuth::Strategies::Wechat>>, @cache_control="max-age=0, private, must-revalidate", @no_cache_control="no-cache">>>, @parsers={#<Mime::Type:0x007fa0dcd90128 @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json, @string="application/json">=>:json}>>, @default_options={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false}, @key="_kano_session", @cookie_only=true>, @env={...}, @delegate={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false, :id=>"17ef4264a6ad06cc7e2e31ce218e632d"}>, "action_dispatch.request.content_type"=>#<Mime::Type:0x007fa0dcd90420 @synonyms=[], @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded">, "warden"=>Warden::Proxy:70164472400600 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, "action_dispatch.request.path_parameters"=>{:controller=>"admin/handymen/certifications", :action=>"update", :id=>"43"}, "rack.request.cookie_hash"=>{"_kano_session"=>"NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ==--8f7965a0d911d61a0be76c2c7806ac61eacad543"}, "rack.request.cookie_string"=>"_kano_session=NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ%3D%3D--8f7965a0d911d61a0be76c2c7806ac61eacad543", "action_dispatch.cookies"=>#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 @key_generator=#<ActiveSupport::CachingKeyGenerator:0x007fa0e06e05b8 @key_generator=#<ActiveSupport::KeyGenerator:0x007fa0e06e05e0 @secret="c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", @iterations=1000>, @cache_keys=#<ThreadSafe::Cache:0x007fa0e06e0590 @backend={"signed_global_ids64"=>"\f\xC4\xC4\xFC#\xA1\x90V\xA0-4\xC2\xF4Q\xE6\xB4\xE7\xD0\x96\xF8t\xBA\\\xAA7\xC3\xBD\x1Aq\xB4O\xFBv\x02I*W\xCA\xB7\xB1U\x9E\xE4\x96\xBD\xFD^O\x8AC)\xDC\xF6\xA2p\xC25\x81\xC0\xC2\xCBH\xE5w", "encrypted cookie64"=>"\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", "signed encrypted cookie64"=>"\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C"}, @default_proc=nil>>, @set_cookies={"request_method"=>{:value=>"PUT", :path=>"/"}}, @delete_cookies={}, @host="localhost", @secure=false, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @cookies={"_kano_session"=>"NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ==--8f7965a0d911d61a0be76c2c7806ac61eacad543", "request_method"=>"PUT"}, @committed=false, @encrypted=#<ActionDispatch::Cookies::EncryptedCookieJar:0x007fa0e2202940 @parent_jar=#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 ...>, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @encryptor=#<ActiveSupport::MessageEncryptor:0x007fa0dd9ffcb0 @secret="\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", @sign_secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007fa0dd9ffbe8 @secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=ActiveSupport::MessageEncryptor::NullSerializer>>, @signed_or_encrypted=#<ActionDispatch::Cookies::EncryptedCookieJar:0x007fa0e2202940 @parent_jar=#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 ...>, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @encryptor=#<ActiveSupport::MessageEncryptor:0x007fa0dd9ffcb0 @secret="\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", @sign_secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007fa0dd9ffbe8 @secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=ActiveSupport::MessageEncryptor::NullSerializer>>>, "action_dispatch.request.unsigned_session_cookie"=>{"session_id"=>"17ef4264a6ad06cc7e2e31ce218e632d", "warden.user.account.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "warden.user.user.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "_csrf_token"=>"xwF4opR7oe+pOvCmPeTqrEOoH2hjIHpVWLBsYy6fDNM="}, "action_controller.instance"=>#<Admin::Handymen::CertificationsController:0x007fa0e0a574f8 @_action_has_layout=true, @_routes=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=#<ActionDispatch::Request:0x007fa0e0a573b8 ...>, @_response=#<ActionDispatch::Response:0x007fa0e0a57368 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fa0e0a57278>, @stream=#<ActionDispatch::Response::Buffer:0x007fa0e0a571b0 @response=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @buf=[], @closed=false>, @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff"}, @status=200, @sending_file=false, @blank=false, @cv=#<MonitorMixin::ConditionVariable:0x007fa0e0a57188 @monitor=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @cond=#<Thread::ConditionVariable:0x007fa0e0a57160>>, @committed=false, @sending=false, @sent=false, @content_type=nil, @charset=nil, @cache_control={}, @etag=nil, @request=#<ActionDispatch::Request:0x007fa0e0a573b8 ...>>, @_env={...}, @_lookup_context=#<ActionView::LookupContext:0x007fa0e0a56d78 @details_key=nil, @details={:locale=>[:"zh-CN"], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :slim, :jbuilder]}, @skip_default_locale=false, @cache=true, @prefixes=["admin/handymen/certifications", "admin/application"], @rendered_format=nil, @view_paths=#<ActionView::PathSet:0x007fa0e0a56cb0 @paths=[#<ActionView::OptimizedFileSystemResolver:0x007fa0e2400f08 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2400ee0 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2400eb8 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/my_rails/kano/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2401660 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2401638 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2401610 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/kaminari-0.16.3/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e24028a8 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2402880 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2402858 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/china_city-0.0.4/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2403410 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e24033e8 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e24033c0 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/devise-3.4.1/app/views">]>>, @_action_name="update", @_response_body=nil, @__react_component_helper=#<React::Rails::ComponentMount:0x007fa0e0a376f8>, @current_user=#<User id: 1, email: "[email protected]", encrypted_password: "$2a$10$L6eoo/WZILLlZewSK0R8g.6ay09W1mH0y3blmsg/kFy...", phone: "13107485756", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 166, current_sign_in_at: "2016-01-24 14:04:28", last_sign_in_at: "2016-01-24 14:04:28", current_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, last_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, admin: true, coins: 0, name: "曲先生", provider: "wechat", uid: "abcde", nickname: "", gender: nil, wechat_headimgurl: nil, created_at: "2015-10-23 12:09:35", updated_at: "2016-01-24 14:04:28", type: "User", primary_address_id: 1>, @_params={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}>, "action_dispatch.request.request_parameters"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过"}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, "action_dispatch.request.formats"=>[#<Mime::Type:0x007fa0dcd99f98 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">]}, @filtered_parameters={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, @filtered_env=nil, @filtered_path=nil, @protocol=nil, @port=nil, @method=nil, @request_method="PUT", @remote_ip=nil, @original_fullpath=nil, @fullpath="/alpha/handymen/certifications/43", @ip=nil, @uuid=nil>

@_response  

#<ActionDispatch::Response:0x007fa0e0a57368 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fa0e0a57278>, @stream=#<ActionDispatch::Response::Buffer:0x007fa0e0a571b0 @response=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @buf=[], @closed=false>, @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff"}, @status=200, @sending_file=false, @blank=false, @cv=#<MonitorMixin::ConditionVariable:0x007fa0e0a57188 @monitor=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @cond=#<Thread::ConditionVariable:0x007fa0e0a57160>>, @committed=false, @sending=false, @sent=false, @content_type=nil, @charset=nil, @cache_control={}, @etag=nil, @request=#<ActionDispatch::Request:0x007fa0e0a573b8 @env={"CONTENT_LENGTH"=>"212", "CONTENT_TYPE"=>"application/x-www-form-urlencoded", "GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/alpha/handymen/certifications/43", "QUERY_STRING"=>"", "REMOTE_ADDR"=>"127.0.0.1", "REMOTE_HOST"=>"127.0.0.1", "REQUEST_METHOD"=>"PUT", "REQUEST_URI"=>"http://localhost:3000/alpha/handymen/certifications/43", "SCRIPT_NAME"=>"", "SERVER_NAME"=>"localhost", "SERVER_PORT"=>"3000", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/2.2.3/2015-08-18)", "HTTP_HOST"=>"localhost:3000", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0", "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.7,zh;q=0.3", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_REFERER"=>"http://localhost:3000/alpha/handymen/certifications", "HTTP_COOKIE"=>"_kano_session=NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ%3D%3D--8f7965a0d911d61a0be76c2c7806ac61eacad543", "HTTP_CONNECTION"=>"keep-alive", "rack.version"=>[1, 3], "rack.input"=>#<StringIO:0x007fa0e0f63550>, "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "rack.url_scheme"=>"http", "rack.hijack?"=>true, "rack.hijack"=>#<Proc:0x007fa0e0f63438@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb:76 (lambda)>, "rack.hijack_io"=>nil, "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_PATH"=>"/alpha/handymen/certifications/43", "ORIGINAL_FULLPATH"=>"/alpha/handymen/certifications/43", "ORIGINAL_SCRIPT_NAME"=>"", "action_dispatch.routes"=>#<ActionDispatch::Routing::RouteSet:0x007fa0dc1ddd58>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.redirect_filter"=>[], "action_dispatch.secret_token"=>nil, "action_dispatch.secret_key_base"=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", "action_dispatch.show_exceptions"=>true, "action_dispatch.show_detailed_exceptions"=>true, "action_dispatch.logger"=>#<ActiveSupport::Logger:0x007fa0e2433d40 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x007fa0e2433cc8 @datetime_format=nil>, @formatter=#<ActiveSupport::Logger::SimpleFormatter:0x007fa0e0e4f308 @datetime_format=nil>, @logdev=#<Logger::LogDevice:0x007fa0e2433c78 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<File:/Users/tornado/my_rails/kano/log/development.log>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x007fa0e2433c50 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fa0e2433c00>>>>, "action_dispatch.backtrace_cleaner"=>#<Rails::BacktraceCleaner:0x007fa0e0f32e78 @filters=[#<Proc:0x007fa0e0f32d60@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:14>, #<Proc:0x007fa0e0f32d38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:15>, #<Proc:0x007fa0e0f32d10@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:16>, #<Proc:0x007fa0e0f32928@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:29>], @silencers=[#<Proc:0x007fa0e0f32900@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:19>], @root="/Users/tornado/my_rails/kano/">, "action_dispatch.key_generator"=>#<ActiveSupport::CachingKeyGenerator:0x007fa0e06e05b8 @key_generator=#<ActiveSupport::KeyGenerator:0x007fa0e06e05e0 @secret="c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", @iterations=1000>, @cache_keys=#<ThreadSafe::Cache:0x007fa0e06e0590 @backend={"signed_global_ids64"=>"\f\xC4\xC4\xFC#\xA1\x90V\xA0-4\xC2\xF4Q\xE6\xB4\xE7\xD0\x96\xF8t\xBA\\\xAA7\xC3\xBD\x1Aq\xB4O\xFBv\x02I*W\xCA\xB7\xB1U\x9E\xE4\x96\xBD\xFD^O\x8AC)\xDC\xF6\xA2p\xC25\x81\xC0\xC2\xCBH\xE5w", "encrypted cookie64"=>"\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", "signed encrypted cookie64"=>"\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C"}, @default_proc=nil>>, "action_dispatch.http_auth_salt"=>"http authentication", "action_dispatch.signed_cookie_salt"=>"signed cookie", "action_dispatch.encrypted_cookie_salt"=>"encrypted cookie", "action_dispatch.encrypted_signed_cookie_salt"=>"signed encrypted cookie", "action_dispatch.cookies_serializer"=>:json, "action_dispatch.cookies_digest"=>nil, "ROUTES_70164432219820_SCRIPT_NAME"=>"", "rack.request.form_hash"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过"}, "rack.request.form_vars"=>"utf8=%E2%9C%93&_method=put&authenticity_token=Cbx%2BHG%2Fv5rekgp0s3toD5xW39%2Fs8Z6LJXng1ez5mdQbOvQa%2B%2B5RHWA24bYrjPulLVh%2Fok19H2JwGyFkYEPl51Q%3D%3D&taxon%5Bcertified_status%5D=success&commit=%E9%80%9A%E8%BF%87", "rack.request.form_input"=>#<StringIO:0x007fa0e0f63550>, "rack.methodoverride.original_method"=>"POST", "action_dispatch.request_id"=>"b9a49b46-c019-4f73-8541-040c404b0513", "action_dispatch.remote_ip"=>#<ActionDispatch::RemoteIp::GetIp:0x007fa0e23f8970 @env={...}, @check_ip=true, @proxies=[#<IPAddr: IPv4:127.0.0.1/255.255.255.255>, #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, #<IPAddr: IPv6:fc00:0000:0000:0000:0000:0000:0000:0000/fe00:0000:0000:0000:0000:0000:0000:0000>, #<IPAddr: IPv4:10.0.0.0/255.0.0.0>, #<IPAddr: IPv4:172.16.0.0/255.240.0.0>, #<IPAddr: IPv4:192.168.0.0/255.255.0.0>]>, "rack.session"=>#<ActionDispatch::Request::Session:0x007fa0e0e81858 @by=#<ActionDispatch::Session::CookieStore:0x007fa0e2006808 @app=#<ActionDispatch::Flash:0x007fa0e2006830 @app=#<ActionDispatch::ParamsParser:0x007fa0e20068f8 @app=#<Rack::Head:0x007fa0e2006920 @app=#<Rack::ConditionalGet:0x007fa0e2006948 @app=#<Rack::ETag:0x007fa0e2006998 @app=#<Warden::Manager:0x007fa0e2006a60 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, @app=#<OmniAuth::Strategies::Wechat>>, @cache_control="max-age=0, private, must-revalidate", @no_cache_control="no-cache">>>, @parsers={#<Mime::Type:0x007fa0dcd90128 @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json, @string="application/json">=>:json}>>, @default_options={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false}, @key="_kano_session", @cookie_only=true>, @env={...}, @delegate={"session_id"=>"17ef4264a6ad06cc7e2e31ce218e632d", "warden.user.account.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "warden.user.user.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "_csrf_token"=>"xwF4opR7oe+pOvCmPeTqrEOoH2hjIHpVWLBsYy6fDNM="}, @loaded=true, @exists=true>, "rack.session.options"=>#<ActionDispatch::Request::Session::Options:0x007fa0e0e81808 @by=#<ActionDispatch::Session::CookieStore:0x007fa0e2006808 @app=#<ActionDispatch::Flash:0x007fa0e2006830 @app=#<ActionDispatch::ParamsParser:0x007fa0e20068f8 @app=#<Rack::Head:0x007fa0e2006920 @app=#<Rack::ConditionalGet:0x007fa0e2006948 @app=#<Rack::ETag:0x007fa0e2006998 @app=#<Warden::Manager:0x007fa0e2006a60 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, @app=#<OmniAuth::Strategies::Wechat>>, @cache_control="max-age=0, private, must-revalidate", @no_cache_control="no-cache">>>, @parsers={#<Mime::Type:0x007fa0dcd90128 @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json, @string="application/json">=>:json}>>, @default_options={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false}, @key="_kano_session", @cookie_only=true>, @env={...}, @delegate={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false, :id=>"17ef4264a6ad06cc7e2e31ce218e632d"}>, "action_dispatch.request.content_type"=>#<Mime::Type:0x007fa0dcd90420 @synonyms=[], @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded">, "warden"=>Warden::Proxy:70164472400600 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, "action_dispatch.request.path_parameters"=>{:controller=>"admin/handymen/certifications", :action=>"update", :id=>"43"}, "rack.request.cookie_hash"=>{"_kano_session"=>"NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ==--8f7965a0d911d61a0be76c2c7806ac61eacad543"}, "rack.request.cookie_string"=>"_kano_session=NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ%3D%3D--8f7965a0d911d61a0be76c2c7806ac61eacad543", "action_dispatch.cookies"=>#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 @key_generator=#<ActiveSupport::CachingKeyGenerator:0x007fa0e06e05b8 @key_generator=#<ActiveSupport::KeyGenerator:0x007fa0e06e05e0 @secret="c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", @iterations=1000>, @cache_keys=#<ThreadSafe::Cache:0x007fa0e06e0590 @backend={"signed_global_ids64"=>"\f\xC4\xC4\xFC#\xA1\x90V\xA0-4\xC2\xF4Q\xE6\xB4\xE7\xD0\x96\xF8t\xBA\\\xAA7\xC3\xBD\x1Aq\xB4O\xFBv\x02I*W\xCA\xB7\xB1U\x9E\xE4\x96\xBD\xFD^O\x8AC)\xDC\xF6\xA2p\xC25\x81\xC0\xC2\xCBH\xE5w", "encrypted cookie64"=>"\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", "signed encrypted cookie64"=>"\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C"}, @default_proc=nil>>, @set_cookies={"request_method"=>{:value=>"PUT", :path=>"/"}}, @delete_cookies={}, @host="localhost", @secure=false, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @cookies={"_kano_session"=>"NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ==--8f7965a0d911d61a0be76c2c7806ac61eacad543", "request_method"=>"PUT"}, @committed=false, @encrypted=#<ActionDispatch::Cookies::EncryptedCookieJar:0x007fa0e2202940 @parent_jar=#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 ...>, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @encryptor=#<ActiveSupport::MessageEncryptor:0x007fa0dd9ffcb0 @secret="\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", @sign_secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007fa0dd9ffbe8 @secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=ActiveSupport::MessageEncryptor::NullSerializer>>, @signed_or_encrypted=#<ActionDispatch::Cookies::EncryptedCookieJar:0x007fa0e2202940 @parent_jar=#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 ...>, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @encryptor=#<ActiveSupport::MessageEncryptor:0x007fa0dd9ffcb0 @secret="\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", @sign_secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007fa0dd9ffbe8 @secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=ActiveSupport::MessageEncryptor::NullSerializer>>>, "action_dispatch.request.unsigned_session_cookie"=>{"session_id"=>"17ef4264a6ad06cc7e2e31ce218e632d", "warden.user.account.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "warden.user.user.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "_csrf_token"=>"xwF4opR7oe+pOvCmPeTqrEOoH2hjIHpVWLBsYy6fDNM="}, "action_controller.instance"=>#<Admin::Handymen::CertificationsController:0x007fa0e0a574f8 @_action_has_layout=true, @_routes=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=#<ActionDispatch::Request:0x007fa0e0a573b8 ...>, @_response=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @_env={...}, @_lookup_context=#<ActionView::LookupContext:0x007fa0e0a56d78 @details_key=nil, @details={:locale=>[:"zh-CN"], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :slim, :jbuilder]}, @skip_default_locale=false, @cache=true, @prefixes=["admin/handymen/certifications", "admin/application"], @rendered_format=nil, @view_paths=#<ActionView::PathSet:0x007fa0e0a56cb0 @paths=[#<ActionView::OptimizedFileSystemResolver:0x007fa0e2400f08 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2400ee0 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2400eb8 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/my_rails/kano/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2401660 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2401638 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2401610 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/kaminari-0.16.3/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e24028a8 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2402880 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2402858 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/china_city-0.0.4/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2403410 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e24033e8 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e24033c0 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/devise-3.4.1/app/views">]>>, @_action_name="update", @_response_body=nil, @__react_component_helper=#<React::Rails::ComponentMount:0x007fa0e0a376f8>, @current_user=#<User id: 1, email: "[email protected]", encrypted_password: "$2a$10$L6eoo/WZILLlZewSK0R8g.6ay09W1mH0y3blmsg/kFy...", phone: "13107485756", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 166, current_sign_in_at: "2016-01-24 14:04:28", last_sign_in_at: "2016-01-24 14:04:28", current_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, last_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, admin: true, coins: 0, name: "曲先生", provider: "wechat", uid: "abcde", nickname: "", gender: nil, wechat_headimgurl: nil, created_at: "2015-10-23 12:09:35", updated_at: "2016-01-24 14:04:28", type: "User", primary_address_id: 1>, @_params={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}>, "action_dispatch.request.request_parameters"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过"}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, "action_dispatch.request.formats"=>[#<Mime::Type:0x007fa0dcd99f98 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">]}, @filtered_parameters={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, @filtered_env=nil, @filtered_path=nil, @protocol=nil, @port=nil, @method=nil, @request_method="PUT", @remote_ip=nil, @original_fullpath=nil, @fullpath="/alpha/handymen/certifications/43", @ip=nil, @uuid=nil>>

@_env   

{"CONTENT_LENGTH"=>"212", "CONTENT_TYPE"=>"application/x-www-form-urlencoded", "GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/alpha/handymen/certifications/43", "QUERY_STRING"=>"", "REMOTE_ADDR"=>"127.0.0.1", "REMOTE_HOST"=>"127.0.0.1", "REQUEST_METHOD"=>"PUT", "REQUEST_URI"=>"http://localhost:3000/alpha/handymen/certifications/43", "SCRIPT_NAME"=>"", "SERVER_NAME"=>"localhost", "SERVER_PORT"=>"3000", "SERVER_PROTOCOL"=>"HTTP/1.1", "SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/2.2.3/2015-08-18)", "HTTP_HOST"=>"localhost:3000", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0", "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.7,zh;q=0.3", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_REFERER"=>"http://localhost:3000/alpha/handymen/certifications", "HTTP_COOKIE"=>"_kano_session=NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ%3D%3D--8f7965a0d911d61a0be76c2c7806ac61eacad543", "HTTP_CONNECTION"=>"keep-alive", "rack.version"=>[1, 3], "rack.input"=>#<StringIO:0x007fa0e0f63550>, "rack.errors"=>#<IO:<STDERR>>, "rack.multithread"=>true, "rack.multiprocess"=>false, "rack.run_once"=>false, "rack.url_scheme"=>"http", "rack.hijack?"=>true, "rack.hijack"=>#<Proc:0x007fa0e0f63438@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb:76 (lambda)>, "rack.hijack_io"=>nil, "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_PATH"=>"/alpha/handymen/certifications/43", "ORIGINAL_FULLPATH"=>"/alpha/handymen/certifications/43", "ORIGINAL_SCRIPT_NAME"=>"", "action_dispatch.routes"=>#<ActionDispatch::Routing::RouteSet:0x007fa0dc1ddd58>, "action_dispatch.parameter_filter"=>[:password], "action_dispatch.redirect_filter"=>[], "action_dispatch.secret_token"=>nil, "action_dispatch.secret_key_base"=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", "action_dispatch.show_exceptions"=>true, "action_dispatch.show_detailed_exceptions"=>true, "action_dispatch.logger"=>#<ActiveSupport::Logger:0x007fa0e2433d40 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x007fa0e2433cc8 @datetime_format=nil>, @formatter=#<ActiveSupport::Logger::SimpleFormatter:0x007fa0e0e4f308 @datetime_format=nil>, @logdev=#<Logger::LogDevice:0x007fa0e2433c78 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<File:/Users/tornado/my_rails/kano/log/development.log>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x007fa0e2433c50 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fa0e2433c00>>>>, "action_dispatch.backtrace_cleaner"=>#<Rails::BacktraceCleaner:0x007fa0e0f32e78 @filters=[#<Proc:0x007fa0e0f32d60@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:14>, #<Proc:0x007fa0e0f32d38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:15>, #<Proc:0x007fa0e0f32d10@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:16>, #<Proc:0x007fa0e0f32928@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:29>], @silencers=[#<Proc:0x007fa0e0f32900@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.4/lib/rails/backtrace_cleaner.rb:19>], @root="/Users/tornado/my_rails/kano/">, "action_dispatch.key_generator"=>#<ActiveSupport::CachingKeyGenerator:0x007fa0e06e05b8 @key_generator=#<ActiveSupport::KeyGenerator:0x007fa0e06e05e0 @secret="c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", @iterations=1000>, @cache_keys=#<ThreadSafe::Cache:0x007fa0e06e0590 @backend={"signed_global_ids64"=>"\f\xC4\xC4\xFC#\xA1\x90V\xA0-4\xC2\xF4Q\xE6\xB4\xE7\xD0\x96\xF8t\xBA\\\xAA7\xC3\xBD\x1Aq\xB4O\xFBv\x02I*W\xCA\xB7\xB1U\x9E\xE4\x96\xBD\xFD^O\x8AC)\xDC\xF6\xA2p\xC25\x81\xC0\xC2\xCBH\xE5w", "encrypted cookie64"=>"\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", "signed encrypted cookie64"=>"\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C"}, @default_proc=nil>>, "action_dispatch.http_auth_salt"=>"http authentication", "action_dispatch.signed_cookie_salt"=>"signed cookie", "action_dispatch.encrypted_cookie_salt"=>"encrypted cookie", "action_dispatch.encrypted_signed_cookie_salt"=>"signed encrypted cookie", "action_dispatch.cookies_serializer"=>:json, "action_dispatch.cookies_digest"=>nil, "ROUTES_70164432219820_SCRIPT_NAME"=>"", "rack.request.form_hash"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过"}, "rack.request.form_vars"=>"utf8=%E2%9C%93&_method=put&authenticity_token=Cbx%2BHG%2Fv5rekgp0s3toD5xW39%2Fs8Z6LJXng1ez5mdQbOvQa%2B%2B5RHWA24bYrjPulLVh%2Fok19H2JwGyFkYEPl51Q%3D%3D&taxon%5Bcertified_status%5D=success&commit=%E9%80%9A%E8%BF%87", "rack.request.form_input"=>#<StringIO:0x007fa0e0f63550>, "rack.methodoverride.original_method"=>"POST", "action_dispatch.request_id"=>"b9a49b46-c019-4f73-8541-040c404b0513", "action_dispatch.remote_ip"=>#<ActionDispatch::RemoteIp::GetIp:0x007fa0e23f8970 @env={...}, @check_ip=true, @proxies=[#<IPAddr: IPv4:127.0.0.1/255.255.255.255>, #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, #<IPAddr: IPv6:fc00:0000:0000:0000:0000:0000:0000:0000/fe00:0000:0000:0000:0000:0000:0000:0000>, #<IPAddr: IPv4:10.0.0.0/255.0.0.0>, #<IPAddr: IPv4:172.16.0.0/255.240.0.0>, #<IPAddr: IPv4:192.168.0.0/255.255.0.0>]>, "rack.session"=>#<ActionDispatch::Request::Session:0x007fa0e0e81858 @by=#<ActionDispatch::Session::CookieStore:0x007fa0e2006808 @app=#<ActionDispatch::Flash:0x007fa0e2006830 @app=#<ActionDispatch::ParamsParser:0x007fa0e20068f8 @app=#<Rack::Head:0x007fa0e2006920 @app=#<Rack::ConditionalGet:0x007fa0e2006948 @app=#<Rack::ETag:0x007fa0e2006998 @app=#<Warden::Manager:0x007fa0e2006a60 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, @app=#<OmniAuth::Strategies::Wechat>>, @cache_control="max-age=0, private, must-revalidate", @no_cache_control="no-cache">>>, @parsers={#<Mime::Type:0x007fa0dcd90128 @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json, @string="application/json">=>:json}>>, @default_options={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false}, @key="_kano_session", @cookie_only=true>, @env={...}, @delegate={"session_id"=>"17ef4264a6ad06cc7e2e31ce218e632d", "warden.user.account.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "warden.user.user.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "_csrf_token"=>"xwF4opR7oe+pOvCmPeTqrEOoH2hjIHpVWLBsYy6fDNM="}, @loaded=true, @exists=true>, "rack.session.options"=>#<ActionDispatch::Request::Session::Options:0x007fa0e0e81808 @by=#<ActionDispatch::Session::CookieStore:0x007fa0e2006808 @app=#<ActionDispatch::Flash:0x007fa0e2006830 @app=#<ActionDispatch::ParamsParser:0x007fa0e20068f8 @app=#<Rack::Head:0x007fa0e2006920 @app=#<Rack::ConditionalGet:0x007fa0e2006948 @app=#<Rack::ETag:0x007fa0e2006998 @app=#<Warden::Manager:0x007fa0e2006a60 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, @app=#<OmniAuth::Strategies::Wechat>>, @cache_control="max-age=0, private, must-revalidate", @no_cache_control="no-cache">>>, @parsers={#<Mime::Type:0x007fa0dcd90128 @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json, @string="application/json">=>:json}>>, @default_options={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false}, @key="_kano_session", @cookie_only=true>, @env={...}, @delegate={:path=>"/", :domain=>nil, :expire_after=>nil, :secure=>false, :httponly=>true, :defer=>false, :renew=>false, :id=>"17ef4264a6ad06cc7e2e31ce218e632d"}>, "action_dispatch.request.content_type"=>#<Mime::Type:0x007fa0dcd90420 @synonyms=[], @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded">, "warden"=>Warden::Proxy:70164472400600 @config={:default_scope=>:account, :scope_defaults=>{}, :default_strategies=>{:account=>[:database_authenticatable, :rememberable, :rememberable, :database_authenticatable], :user=>[:rememberable, :database_authenticatable], :handyman=>[:rememberable, :database_authenticatable]}, :intercept_401=>false, :failure_app=>#<Devise::Delegator:0x007fa0e2820a98>}, "action_dispatch.request.path_parameters"=>{:controller=>"admin/handymen/certifications", :action=>"update", :id=>"43"}, "rack.request.cookie_hash"=>{"_kano_session"=>"NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ==--8f7965a0d911d61a0be76c2c7806ac61eacad543"}, "rack.request.cookie_string"=>"_kano_session=NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ%3D%3D--8f7965a0d911d61a0be76c2c7806ac61eacad543", "action_dispatch.cookies"=>#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 @key_generator=#<ActiveSupport::CachingKeyGenerator:0x007fa0e06e05b8 @key_generator=#<ActiveSupport::KeyGenerator:0x007fa0e06e05e0 @secret="c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", @iterations=1000>, @cache_keys=#<ThreadSafe::Cache:0x007fa0e06e0590 @backend={"signed_global_ids64"=>"\f\xC4\xC4\xFC#\xA1\x90V\xA0-4\xC2\xF4Q\xE6\xB4\xE7\xD0\x96\xF8t\xBA\\\xAA7\xC3\xBD\x1Aq\xB4O\xFBv\x02I*W\xCA\xB7\xB1U\x9E\xE4\x96\xBD\xFD^O\x8AC)\xDC\xF6\xA2p\xC25\x81\xC0\xC2\xCBH\xE5w", "encrypted cookie64"=>"\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", "signed encrypted cookie64"=>"\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C"}, @default_proc=nil>>, @set_cookies={"request_method"=>{:value=>"PUT", :path=>"/"}}, @delete_cookies={}, @host="localhost", @secure=false, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @cookies={"_kano_session"=>"NWIyRkJHUkVNU2Y0UTl3Zy9sR2R0OHZTemlwVm9ObWNFWW4yWHdDZmpLK21DaDBadFRMSWQ2WFhxdjk5RDFsY09QdXpkUzVlckhwdGdLS09xNFdidXFHWHBQbnFLdVZOQy9SUUQ1dzNCazNlMmxNWHFTQzlINjAwd1VVeXhCa3p2ZlYreENKYktURjBkQjJkT040TEtjUHdlNVFtNmVSdDVEdXpabGNaVmlWTURUSzBqMkw5dUxrcHpvZzNTdWhQSkxoRVdSS3VueklTQlpPTWlLK1hHYlhRdXZDNmJkNmo0UDZ3YUVvbmZXNms5aVBVOEpheHNjdjdnVnQwUmRsWG5lUE1QN2V4ZWpRK0NWUVAvMzNpcjdIaGhqeXBuYVpCWXZzRVVCUHRJY1ozcjNxZWlZVVNobnRaYzFtTi80cTYtLXlPUHRHcEk4cm10RXRNNlV1N0FpeVE9PQ==--8f7965a0d911d61a0be76c2c7806ac61eacad543", "request_method"=>"PUT"}, @committed=false, @encrypted=#<ActionDispatch::Cookies::EncryptedCookieJar:0x007fa0e2202940 @parent_jar=#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 ...>, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @encryptor=#<ActiveSupport::MessageEncryptor:0x007fa0dd9ffcb0 @secret="\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", @sign_secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007fa0dd9ffbe8 @secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=ActiveSupport::MessageEncryptor::NullSerializer>>, @signed_or_encrypted=#<ActionDispatch::Cookies::EncryptedCookieJar:0x007fa0e2202940 @parent_jar=#<ActionDispatch::Cookies::CookieJar:0x007fa0e2203070 ...>, @options={:signed_cookie_salt=>"signed cookie", :encrypted_cookie_salt=>"encrypted cookie", :encrypted_signed_cookie_salt=>"signed encrypted cookie", :secret_token=>nil, :secret_key_base=>"c1c5f900de5ee57db8ca837ce0e31005cb0a684442b3a94dc383faea6f31ef0371e983e2c2f62d22933810b356c53265ac892446948c453c41ccce7c92999ab6", :upgrade_legacy_signed_cookies=>false, :serializer=>:json, :digest=>nil}, @encryptor=#<ActiveSupport::MessageEncryptor:0x007fa0dd9ffcb0 @secret="\xF6t\x92\xA6S\xEBT\x80\xC1\b\x0E\r@\xEE\xF2\x16\x86\xA8\x0E6\xBDn\x90I\xC3q\x85\x88\xF9S\x06\x95x1\x86\x03z\xFE\xE8\x7F>\xFB\xD3\xD1\xB5\xFC\x190\x02\xCDbq\t\x95];\x0F\xD0\xF6>\xFD\xBA\xA7W", @sign_secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @cipher="aes-256-cbc", @verifier=#<ActiveSupport::MessageVerifier:0x007fa0dd9ffbe8 @secret="\xA8\e\xA5-\xBB9\xEE*\xF2\x8Bj\xFB'i6\xE1\x90\xC6_)\xD2\xCAR\xDD\xCF\xDC\x06\xA7\x17\xFA5\xE9\xF1&\xF83\x0E\x7Fw\xA4\xD4\xEF\x90\xA1\x13H;\xF2SN\xFBY\xF8\x1A\xBA\xD9\x8E\xC1\x80\v\r\xF5l\x8C", @digest="SHA1", @serializer=ActiveSupport::MessageEncryptor::NullSerializer>, @serializer=ActiveSupport::MessageEncryptor::NullSerializer>>>, "action_dispatch.request.unsigned_session_cookie"=>{"session_id"=>"17ef4264a6ad06cc7e2e31ce218e632d", "warden.user.account.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "warden.user.user.key"=>[[1], "$2a$10$L6eoo/WZILLlZewSK0R8g."], "_csrf_token"=>"xwF4opR7oe+pOvCmPeTqrEOoH2hjIHpVWLBsYy6fDNM="}, "action_controller.instance"=>#<Admin::Handymen::CertificationsController:0x007fa0e0a574f8 @_action_has_layout=true, @_routes=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=#<ActionDispatch::Request:0x007fa0e0a573b8 @env={...}, @filtered_parameters={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, @filtered_env=nil, @filtered_path=nil, @protocol=nil, @port=nil, @method=nil, @request_method="PUT", @remote_ip=nil, @original_fullpath=nil, @fullpath="/alpha/handymen/certifications/43", @ip=nil, @uuid=nil>, @_response=#<ActionDispatch::Response:0x007fa0e0a57368 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x007fa0e0a57278>, @stream=#<ActionDispatch::Response::Buffer:0x007fa0e0a571b0 @response=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @buf=[], @closed=false>, @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff"}, @status=200, @sending_file=false, @blank=false, @cv=#<MonitorMixin::ConditionVariable:0x007fa0e0a57188 @monitor=#<ActionDispatch::Response:0x007fa0e0a57368 ...>, @cond=#<Thread::ConditionVariable:0x007fa0e0a57160>>, @committed=false, @sending=false, @sent=false, @content_type=nil, @charset=nil, @cache_control={}, @etag=nil, @request=#<ActionDispatch::Request:0x007fa0e0a573b8 @env={...}, @filtered_parameters={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, @filtered_env=nil, @filtered_path=nil, @protocol=nil, @port=nil, @method=nil, @request_method="PUT", @remote_ip=nil, @original_fullpath=nil, @fullpath="/alpha/handymen/certifications/43", @ip=nil, @uuid=nil>>, @_env={...}, @_lookup_context=#<ActionView::LookupContext:0x007fa0e0a56d78 @details_key=nil, @details={:locale=>[:"zh-CN"], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :slim, :jbuilder]}, @skip_default_locale=false, @cache=true, @prefixes=["admin/handymen/certifications", "admin/application"], @rendered_format=nil, @view_paths=#<ActionView::PathSet:0x007fa0e0a56cb0 @paths=[#<ActionView::OptimizedFileSystemResolver:0x007fa0e2400f08 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2400ee0 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2400eb8 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/my_rails/kano/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2401660 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2401638 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2401610 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/kaminari-0.16.3/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e24028a8 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2402880 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2402858 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/china_city-0.0.4/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2403410 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e24033e8 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e24033c0 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/devise-3.4.1/app/views">]>>, @_action_name="update", @_response_body=nil, @__react_component_helper=#<React::Rails::ComponentMount:0x007fa0e0a376f8>, @current_user=#<User id: 1, email: "[email protected]", encrypted_password: "$2a$10$L6eoo/WZILLlZewSK0R8g.6ay09W1mH0y3blmsg/kFy...", phone: "13107485756", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 166, current_sign_in_at: "2016-01-24 14:04:28", last_sign_in_at: "2016-01-24 14:04:28", current_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, last_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, admin: true, coins: 0, name: "曲先生", provider: "wechat", uid: "abcde", nickname: "", gender: nil, wechat_headimgurl: nil, created_at: "2015-10-23 12:09:35", updated_at: "2016-01-24 14:04:28", type: "User", primary_address_id: 1>, @_params={"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}>, "action_dispatch.request.request_parameters"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过"}, "rack.request.query_string"=>"", "rack.request.query_hash"=>{}, "action_dispatch.request.query_parameters"=>{}, "action_dispatch.request.parameters"=>{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}, "action_dispatch.request.formats"=>[#<Mime::Type:0x007fa0dcd99f98 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">]}

@_lookup_context    

#<ActionView::LookupContext:0x007fa0e0a56d78 @details_key=nil, @details={:locale=>[:"zh-CN"], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :slim, :jbuilder]}, @skip_default_locale=false, @cache=true, @prefixes=["admin/handymen/certifications", "admin/application"], @rendered_format=nil, @view_paths=#<ActionView::PathSet:0x007fa0e0a56cb0 @paths=[#<ActionView::OptimizedFileSystemResolver:0x007fa0e2400f08 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2400ee0 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2400eb8 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/my_rails/kano/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2401660 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2401638 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2401610 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/kaminari-0.16.3/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e24028a8 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e2402880 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e2402858 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/china_city-0.0.4/app/views">, #<ActionView::OptimizedFileSystemResolver:0x007fa0e2403410 @pattern=":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}", @cache=#<ActionView::Resolver::Cache:0x007fa0e24033e8 @data=#<ActionView::Resolver::Cache::SmallCache:0x007fa0e24033c0 @backend={}, @default_proc=#<Proc:0x007fa0e02ebb38@/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/actionview-4.2.4/lib/action_view/template/resolver.rb:49 (lambda)>>>, @path="/Users/tornado/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/devise-3.4.1/app/views">]>>

@_action_name   

"update"

@_response_body 

nil

@__react_component_helper   

#<React::Rails::ComponentMount:0x007fa0e0a376f8>

@current_user   

#<User id: 1, email: "[email protected]", encrypted_password: "$2a$10$L6eoo/WZILLlZewSK0R8g.6ay09W1mH0y3blmsg/kFy...", phone: "13107485756", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 166, current_sign_in_at: "2016-01-24 14:04:28", last_sign_in_at: "2016-01-24 14:04:28", current_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, last_sign_in_ip: #<IPAddr: IPv6:0000:0000:0000:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>, admin: true, coins: 0, name: "曲先生", provider: "wechat", uid: "abcde", nickname: "", gender: nil, wechat_headimgurl: nil, created_at: "2015-10-23 12:09:35", updated_at: "2016-01-24 14:04:28", type: "User", primary_address_id: 1>

@_params    

{"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"Cbx+HG/v5rekgp0s3toD5xW39/s8Z6LJXng1ez5mdQbOvQa++5RHWA24bYrjPulLVh/ok19H2JwGyFkYEPl51Q==", "taxon"=>{"certified_status"=>"success"}, "commit"=>"通过", "controller"=>"admin/handymen/certifications", "action"=>"update", "id"=>"43"}

订单流转功能

@wangxiran: 第四就是希望加入订单流转功能,就是如果师傅上门发现无法修理,点击某个选项,可将订单再次放回看版供其他师傅接取,避免了用户只能取消并再次下单的麻烦

维修补助、问题和用例

在Slack上面有一个版本比较早的描述关于师傅补助的文件:

补助现阶段已月为单位计量,每一个月,师傅接的前80单,每单补助5元钱,80单之后,每单补助10元钱。每单的补助在用户支付完成后,同师傅维修金额一起自动结算进师傅钱包的总金额内。

设置根据是一周工作5天,每天按接取4单计算,一个月为80单,其余单数为周六,日的额外加班时间接取的,因此将补助提高至10元也是合情合理的。

夜间补助(应为夜间维修价格)为基础系统定价*1.5倍,夜间补助时间段为预约维修时间定在夜间8点至夜间12点之间的订单。

当用户的预约修理时间定在晚上8点至晚上12点之间的时候,系统报价(车马费+基础维修费)显示金额将自动x1.5倍。同时在报价框下方出现一行提示:此订单为夜间维修订单,需额外征收夜间维修费(基础订单价格x1.5)。(这个1.2、1.5倍价格浮动已经更新在wiki,以最新版本为准)

上面的需求描述(前两段)还有没有什么需要变动的地方?

80单之前每单师傅补充5元,80单之后每单师傅补充10元。

下面是我的一部分问题:

  • 每单的最小成交金额是否有要求?
  • 每单获得补助的最小成交金额是否有要求?
  • 80单之后每个师傅无论多少单都可以每单获得10元补助吗?
  • 上述问题,有没有相关的限制标准和策略,如果有的话需不需要随时更改策略?(比如在后台中供管理人员灵活定制,可能实现比较复杂
  • 当前的应用支付方式分为“现金支付”和“微信支付”,是不是只有“微信支付”才能获得补助?如果是,之前说的“前80单”“后80单”(以及涉及前面几个问题的订单都需要指明)指的是不是只有使用微信支付的订单?
  • 师傅获得补助,师傅在具体哪个环节得到信息显示和通知?

上述问题也可以按照我自己的理解来实现,不过最好能够留意一下其中的重要问题,以免实现与核心需求不一致。更改需求实现,等于之前做了很多无用功,效率会低很多~

我觉得最好的解答问题的办法是 用例 + 原型图~
用例 ≠ 需求文字说明,需要针对不同的角色(师傅还是普通用户),描述他们关于这个需求可以选择的动作路径:

角色:用户
用例:放大象
前提:没有大象在冰箱里面
步骤:
1.1 把冰箱门打开
1.2 把大象放进冰箱里面
1.3 把冰箱门关上
结果:大象在冰箱里面
角色:大象
用例:进冰箱
前提:冰箱门是打开的
步骤:
1.a 冰箱足够大:跳进冰箱里面去
1.b 冰箱不够大:Run!
1.a.1 等待用户把门关上
结果:
- a路径:在冰箱里面等待用户把门关上
- b路径:Run baby run!

UPDATE
刚刚看到zhuxiang发在business channel上的文件,这个应该是最新版本:

补助现阶段已月为单位计量,每一个月,师傅接的前80单,每单补助5元钱,80单之后,每单补助10元钱。每单的补助在用户支付完成后,同师傅维修金额一起自动结算进师傅钱包的总金额内。

设置根据是一周工作5天,每天按接取4单计算,一个月为80单,其余单数为周六,日的额外加班时间接取的,因此将补助提高至10元也是合情合理的。

夜间补助时间段为预约维修时间定在20:00-24:00点之间的订单。其中20:00-22:00的补助倍数是1.2倍,22:00-24:00的补助倍数是1.5倍。

当用户的预约修理时间定在晚上8点至晚上12点之间的时候,系统报价(车马费+基础维修费)显示金额将自动乘以倍数。同时在报价框下方出现一行提示:此订单为夜间维修订单,需额外征收夜间维修费(基础订单价格乘以倍数)。例如基础总价格为x元,当前的倍数为β倍(1.2或者1.5),则夜间系统报价为y=β×x元。

后台管理相关用例 -> 权限管理

简单看了一下 Wiki,关于“权限管理”有一些不太清楚的地方:

在后台管理相关用例 Wiki 的 7 在权限管理的新开用户页面中新建用户并添加权限8 在权限管理的权限管理页面中修改用户信息与用户权限 中,

作为一个(角色):管理员,我希望(方式):查看新开用户 页面,这样我就可以(目的):可以为新员工建立档案并添加权限。

员工具体指的是哪类用户呢?

7.7 在用户部门后输入新建用户的现任部门。

用户部门具体包括哪些项目呢?

另外用户权限现在具体包括哪些呢?如果这个暂时不明确,我们打算在 version 1.0 暂时只考虑 full control 权限的情形。

Dashboard无法定义在attributes(resource)之外的searching attribute

@hymRedemption 假设我希望在 Order Dashboard 中定义以下搜索属性:

  search("search_admin_orders_path") do |s|
    s.eq "id"
    s.eq "user.id"
    s.eq "handyman.id"

    # FIXME: There is no need to ensure the searching attributes are defined in
    # the `attributes("Order")` fields, since the latter is only used for
    # visually displaying explicit columns in the table of the index page.
    # Therefore we should allow the attributes not explicitly demonstrated in
    # the model attribute fields for searching purposes.

    s.eq "user.phone"
    s.eq "handyman.phone"
  end

因为后面两个 phone 属性未在 attributes("Order") 中得到定义,访问该页面时会抛出异常。这是不是不太符合预期呢?因为 attributes("Order") 中定义的是订单列表中显式展示的列,但搜索的属性应该可以不在其中,我觉得两者应该没有直接的关联。

师傅以及用户刷单的方法以及应对策略

刷单是指师傅为了获取补贴而采取虚构用户或者联合真实用户进行自己或者团体发送订单,自己或者团体再接收订单,从而谋取利益的一种手段,即订单发起者和订单接收者为同一个个体或者团体。下面讨论刷单的可能途径以及应对策略。

  • 师傅注册若干的小号进行刷单

途径:师傅M注册了若干个虚拟用户S(水军),每天利用这些假用户S进行下单,师傅M迅速接单,师傅在一段时间后点击完成订单(迅速完成订单也是容易被检测出来为刷单行为,这个本身有刷单成本),用户S微信结账,师傅M获取每单的补助。

应对策略:每日将完成订单数5单以上的师傅进行监控(4-5单一天是合理工作数量),同时定期检查单量较高的师傅,以5天为一期限,如果有师傅多次在被监控,且每日向其发送订单的用户高度相似或完全一样,则可认为师傅存在刷单的嫌疑,客服将通过电话回访用户S进行确认。如果订单的类型和用户不一致,并且持续若干天,随机抽取用户S进行回访进行电话确认,来确定是否存在刷单(因为每次下单都需要留用户的手机号,所以其实每天注册大量新用户微信下单是非常困难的,所以在这种情况下,师傅大致拥有刷单的水军数量是固定的)。

处罚:采取刷1罚3的策略,即若此单的补贴是5元,则扣除15元做为罚款。

后台订单显示顺序

现在的后台订单是按照什么排序方式显示的呢?好像最新创建的订单不能及时地显示出来。建议如果时间有限、在没有支持多种排序方式的情况下,可以先把默认排序方式调整成按更新时间(updated_at)倒序排序比较好。

用户维修项目价格显示

用户维修项目价格显示这个需求现在还是不够明确,可能需要形成相关的wiki需求文档。搬运一下前几天在slack上发布的内容:

关于这个需求上还有几个问题:

  1. “80封顶”这些内容具体该怎么显示,直接显示文字吗?我之前以为只是一个参考价格,现在回过头来看还有“封顶”这样的内容。
  2. 除了显示参考价格之外,还要具体显示什么信息?有没有关于具体维修服务的描述信息?还是只显示参考价格?

简化下单界面

@wangxiran 最近得到的反馈,一些师傅和用户对微信和网络并不足够熟悉,还是觉得下单、接单过程有些繁琐。目前的想法是新增一个一键下单页面(只包含 电话号码、维修项目 这两项最必要的信息),其它信息通过可以在电话中交流确定。这样可以同时兼顾对互联网熟悉程度不同的各类群体,更好地满足用户对信息填写的不同意愿需求。

形式上这个页面可以作为一个独立的页面,也可以作为唯一的页面(其它信息作为这个页面的高级选项,用户可以自愿填写)。

进入“员工管理”时抛出 NoMethodError 异常

NoMethodError at /alpha/managers/accounts
undefined method `search_params' for nil:NilClass

app/controllers/admin/managers/accounts_controller.rb:6

class Admin::Managers::AccountsController < Admin::ApplicationController
  helper_method :dashboard
  def index
    q_params = dashboard.search_params(params)
    @search = Account.where(admin: true).ransack(q_params)
    @managers = @search.result.page(params[:page]).per(10)
  end

Yaml 文件的测试问题

Taxon::Config

现在 services/taxon/config 是专门用于读取 taxon.yml 文件中的信息的,这种如何去测试了,也就是如何在测试中去指定一个测试用的 yml 文件?

Taxon

Taxon model 中的一些 validation,会用到 Taxon::Config 提供的方法,但是这里用 Rspec 提供的 Mock 机制我实验了一下并不起作用,因为 Rspec mock 都是在测试代码中显示调用才会起作用,而对于代码内部(例如 Taxon 的 methods 内部去调用 Taxon::Config)调用时,mock 机制并不起作用。

举例说明:
对于 Taxon::Config.certified_statuses 方法, 如果我在 Rspec 中 mock 这个方法输出是 { :a, :b, :c }
我在 Rspec 中 expect(Taxon::Config.certified_statuses).to eq { a:, :b, :c} 输出是通过的。

但是当 Taxon.update(certified_statuses: :a) 的时候,会抛出异常(因为 validates :certified_statuses :inclusion { in: Taxon::Config.certified_statuses }),其说明 certified_statuses 只能是在 config/taxon.yml 中我们定义的文件中的那些取值。

所以 Rspec 中的 mock 这时候并不起作用

前端并发问题

前面所解决的问题,主要是针对后台高吞吐量的时候,保证逻辑执行正确所进行的并发控制。

但是还有一种并发控制是前端的,例如下面的场景:
一个管理员,对某个技能进行认证,在打开认证页面之后,临时有事出去了 10 多分钟,然后另一个管理员在第一个管理员出去的时候,也正在对师傅技能进行认证,他完成了所有师傅的技能认证。 等一会,第一个管理员回来了,继续在开始打开的认证页面重新进行认证工作。

上面这种场景的并发问题如何解决呢。 我在网上看到一个资料说是用 rails 的乐观锁解决,就是将 lock_version 字段作为 from 的一个属性,通过这种方法来判断。 但是对于后台来说,要是用这个方法,那么所有 model 都要添加这个字段了。因为后台能够对所有模型进行操作。

Page Not Found (404) after session expired

When the user clicks an order link after session expired (signing out or no activity for a moment), the response should be requiring user signing in instead of redirecting to the 404 page.

账号锁定功能实现细节

  • 符号约定:括号中的内容是有待商榷的内容

需求中有账号锁定功能,但是需求并没有说明清楚这个功能想要的效果,所以我在这里写一下我的理解和准备实现的方式。

需求分析

所要达到的效果

使用户不能正常使用我们的服务。
管家用户:不能够接单,(不能够提现)。
普通用户:不能创建新的订单

有待讨论的问题

管家用户:

  1. 锁定账户时,如果存在未完成的订单,是否让管家继续完成
  2. 锁定账户时,如果存在未完成的提现申请,是否让管家继续提现

实现方式

由于需求中由于可以设置账号锁定的持续时间,所以准备对 Account 的 model 进行如下更改。

创建 locked_date 和 punishment_time 两个属性分别存储账户锁定的时间和持续的时间。

用户每次进行“账号锁定受限内容”的操作时,去比较当天的时间和用这两个属性的计算出来的结果。 然后判断是否有权去进行相关操作。

在进行比较时,如果发现惩罚结束,就重置这两个属性为 nil。

完善需求文档1.0

我和 @hymRedemption 在昨天开会以后简单讨论一下最近需要实现的需求,协作编辑了下面这份文档:
https://github.com/nobrick/kano/wiki/Requirements-1.0

我一直在想,咱们是不是也可以学习开源社区极为高效的工作方式,通过这里 Issues 记录和讨论项目需要优先实现的需求和存在的问题,通过 Wiki 来记录项目的其它文档(比如总体的需求说明、发展方向),这样最终每个人都能参与进来,每个人都可以随时修改、补充说明,随时获得项目各个环节的最新进展,这样的**“异步”**协同也许比严重依赖“同步”协同(完全委派一个人来做一件事、然后一部分人等待另一部分人)效率要高很多。

参考:
https://github.com/blog/1124-how-we-use-pull-requests-to-build-github
http://zachholman.com/posts/how-github-works-asynchronous/
http://gettingreal.37signals.com/ch07_Meetings_Are_Toxic.php

财会信息管理的链接跳转

@hymRedemption 现在财会信息管理的页面的内容展示做的不错,但是如果点击一个提现项目,能够自动跳转到这个师傅的详情(或者师傅自己的财会详情)页面可能会更好,使用会方便一些。

device

问题 1

current_user 和 current_handyman 是如何自动产生的?

我猜想是通过 route.rb 中下面代码产生的

 authenticated :handyman  do
...
 end

 authenticated :user  do
...
 end

问题 2

device 是如何将 user 、handyman 和 account 联系上的。 也就是下面这个代码中

 authenticated :handyman  do
...
 end

device 是如何知道去通过 account 模型来进行 authenticate 的?

Locking issue introduced by redis-objects

Models such as Account, Order and Payment which includes Redis::Objects fail to respond AR pessimistic locking methods lock and lock! correctly. Locking calls made to these models may not generated PostgreSQL FOR UPDATE clause as expected. The reason is that redis-objects monkey-patches the existing AR locking methods, without making any namespace instead.

This is referenced in the thread nateware/redis-objects#191

Since this won't be resolved in redis-objects in a short time (and the author seems to be OK with the overriding), we need to fix it on our own.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.