简体   繁体   English

Rails 5.1.6 - 堆栈级别太深

[英]Rails 5.1.6 - Stack level too deep

I'm using Rails 5.1.6 with Puma and MySQL.我在 Puma 和 MySQL 中使用 Rails 5.1.6。 I have the below code in a Rails controller:我在 Rails 控制器中有以下代码:

class ScansController < ApplicationController
  before_action :find_device, only: %i[index new create]
  .
  .
  .
  def create
    @scan = @device.scans.create(scan_params)
    flash[:notice] = t('.success') if @scan.save
    respond_with @scan.device, @scan
  end
  .
  .
  .
  private

  def find_device
    @device = Device.find params[:device_id]
  end

  def scan_params
    params.require(:scan).permit(:photo, :device_id, :reading, :reading_date)
  end
end

And when I send a POST request to this URL the below happens:当我向此 URL 发送 POST 请求时,会发生以下情况:

Started POST "/en/devices/1/scans" for 81.0.89.20 at 2018-04-03 09:39:19 +0000
09:39:19 web.1    | Processing by ScansController#create as HTML
09:39:19 web.1    |   Parameters: {"utf8"=>"✓", "authenticity_token"=>"QFdUs2thGPzJMbcWfApbattFMvnIEfzN1swrVGnbOTx7XbjY0Y3A8PLI1bRxqyBv6xIk9D2t13bfLPAqdSIyzQ==", "scan"=>{"reading_date"=>"2018-04-03T11:39:11", "reading"=>"6"}, "button"=>"", "locale"=>"en", "device_id"=>"1"}
09:39:19 web.1    |   User Load (1.0ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
09:39:19 web.1    |   Device Load (0.6ms)  SELECT  `devices`.* FROM `devices` WHERE `devices`.`id` = 1 LIMIT 1
09:39:19 web.1    |    (0.6ms)  BEGIN
09:39:19 web.1    |    (0.7ms)  ROLLBACK
09:39:19 web.1    | Completed 500 Internal Server Error in 33ms (ActiveRecord: 2.9ms)
09:39:19 web.1    | 
09:39:19 web.1    | 
09:39:19 web.1    |   
09:39:19 web.1    | SystemStackError (stack level too deep):
09:39:19 web.1    |   
09:39:19 web.1    | app/controllers/scans_controller.rb:35:in `create'

Now, line 35 is this line: @scan = @device.scans.create(scan_params)现在,第 35 行是这一行: @scan = @device.scans.create(scan_params)

and this was working well in Rails 4, but now that I migrated to Rails 5.1.6 it produces this behaviior even in my integration tests.这在 Rails 4 中运行良好,但现在我迁移到 Rails 5.1.6,即使在我的集成测试中也会产生这种行为。 I hav no clue what could be the reason for this behavior.我不知道这种行为的原因是什么。 Does anyone sees something my eyes avoided for the last one or two weeks?有没有人看到我的眼睛在过去一两周内避免的东西? Thanx in advance.提前谢谢。

The models:型号:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end

class Scan < ApplicationRecord
  .
  .
  belongs_to :device, inverse_of: :scans
  validates_attachment(
    :photo,
    content_type: {
      content_type: [
        'image/jpeg',
        'image/gif',
        'image/png',
        'image/tiff'
      ]
    }
  )
  with_options unless: @photo.present? do
    validates :reading, presence: true
    validates :reading, numericality: true
    validates :reading_date, presence: true
  end
  .
end

class Device < ApplicationRecord
  .
  .
  has_many :scans, inverse_of: :device, dependent: :restrict_with_error
  validates :unit, presence: true
  validates :name, presence: true
  validates :serial, presence: true, uniqueness: true
  validates :owner, presence: true
  validates :precision, numericality: {
    only_integer: true,
    greater_than_or_equal_to: 0
  }, allow_nil: true
  . 
  .
end

The Full stack trace looks like this:完整堆栈跟踪如下所示:

activesupport (5.1.6) lib/active_support/callbacks.rb:827:in `_run_validate_callbacks'
activemodel (5.1.6) lib/active_model/validations.rb:405:in `run_validations!'
activemodel (5.1.6) lib/active_model/validations/callbacks.rb:114:in `block in run_validations!'
activesupport (5.1.6) lib/active_support/callbacks.rb:131:in `run_callbacks'
activesupport (5.1.6) lib/active_support/callbacks.rb:827:in `_run_validation_callbacks'
activemodel (5.1.6) lib/active_model/validations/callbacks.rb:114:in `run_validations!'
activemodel (5.1.6) lib/active_model/validations.rb:335:in `valid?'
activerecord (5.1.6) lib/active_record/validations.rb:65:in `valid?'
activesupport (5.1.6) lib/active_support/callbacks.rb:422:in `block in inverted_lambda'
activesupport (5.1.6) lib/active_support/callbacks.rb:177:in `block (2 levels) in halting_and_conditional'
activesupport (5.1.6) lib/active_support/callbacks.rb:177:in `each'
activesupport (5.1.6) lib/active_support/callbacks.rb:177:in `all?'
activesupport (5.1.6) lib/active_support/callbacks.rb:177:in `block in halting_and_conditional'
activesupport (5.1.6) lib/active_support/callbacks.rb:507:in `block in invoke_before'
activesupport (5.1.6) lib/active_support/callbacks.rb:507:in `each'
activesupport (5.1.6) lib/active_support/callbacks.rb:507:in `invoke_before'
activesupport (5.1.6) lib/active_support/callbacks.rb:130:in `run_callbacks'
activesupport (5.1.6) lib/active_support/callbacks.rb:827:in `_run_validate_callbacks'
activemodel (5.1.6) lib/active_model/validations.rb:405:in `run_validations!'
activemodel (5.1.6) lib/active_model/validations/callbacks.rb:114:in `block in run_validations!'
activesupport (5.1.6) lib/active_support/callbacks.rb:131:in `run_callbacks'
activesupport (5.1.6) lib/active_support/callbacks.rb:827:in `_run_validation_callbacks'
activemodel (5.1.6) lib/active_model/validations/callbacks.rb:114:in `run_validations!'
activemodel (5.1.6) lib/active_model/validations.rb:335:in `valid?'
activerecord (5.1.6) lib/active_record/validations.rb:65:in `valid?'
activerecord (5.1.6) lib/active_record/validations.rb:82:in `perform_validations'
activerecord (5.1.6) lib/active_record/validations.rb:44:in `save'
activerecord (5.1.6) lib/active_record/attribute_methods/dirty.rb:35:in `save'
activerecord (5.1.6) lib/active_record/transactions.rb:308:in `block (2 levels) in save'
activerecord (5.1.6) lib/active_record/transactions.rb:384:in `block in with_transaction_returning_status'
activerecord (5.1.6) lib/active_record/connection_adapters/abstract/database_statements.rb:233:in `transaction'
activerecord (5.1.6) lib/active_record/transactions.rb:210:in `transaction'
activerecord (5.1.6) lib/active_record/transactions.rb:381:in `with_transaction_returning_status'
activerecord (5.1.6) lib/active_record/transactions.rb:308:in `block in save'
activerecord (5.1.6) lib/active_record/transactions.rb:323:in `rollback_active_record_state!'
activerecord (5.1.6) lib/active_record/transactions.rb:307:in `save'
activerecord (5.1.6) lib/active_record/suppressor.rb:42:in `save'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/active_record_prepend.rb:16:in `block in save'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/transaction.rb:917:in `with_database_metric_name'
newrelic_rpm (5.0.0.342) lib/new_relic/agent.rb:618:in `with_database_metric_name'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/active_record_prepend.rb:15:in `save'
activerecord (5.1.6) lib/active_record/associations/collection_association.rb:371:in `insert_record'
activerecord (5.1.6) lib/active_record/associations/has_many_association.rb:34:in `insert_record'
activerecord (5.1.6) lib/active_record/associations/collection_association.rb:360:in `block (2 levels) in _create_record'
activerecord (5.1.6) lib/active_record/associations/collection_association.rb:447:in `replace_on_target'
activerecord (5.1.6) lib/active_record/associations/collection_association.rb:281:in `add_to_target'
activerecord (5.1.6) lib/active_record/associations/collection_association.rb:358:in `block in _create_record'
activerecord (5.1.6) lib/active_record/associations/collection_association.rb:129:in `block in transaction'
activerecord (5.1.6) lib/active_record/connection_adapters/abstract/database_statements.rb:235:in `block in transaction'
activerecord (5.1.6) lib/active_record/connection_adapters/abstract/transaction.rb:194:in `block in within_new_transaction'
/usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
activerecord (5.1.6) lib/active_record/connection_adapters/abstract/transaction.rb:191:in `within_new_transaction'
activerecord (5.1.6) lib/active_record/connection_adapters/abstract/database_statements.rb:235:in `transaction'
activerecord (5.1.6) lib/active_record/transactions.rb:210:in `transaction'
activerecord (5.1.6) lib/active_record/associations/collection_association.rb:128:in `transaction'
activerecord (5.1.6) lib/active_record/associations/collection_association.rb:357:in `_create_record'
activerecord (5.1.6) lib/active_record/associations/has_many_association.rb:121:in `_create_record'
activerecord (5.1.6) lib/active_record/associations/association.rb:196:in `create'
activerecord (5.1.6) lib/active_record/associations/collection_proxy.rb:347:in `create'
actionpack (5.1.6) lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
actionpack (5.1.6) lib/abstract_controller/base.rb:186:in `process_action'
actionpack (5.1.6) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (5.1.6) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (5.1.6) lib/active_support/callbacks.rb:108:in `block in run_callbacks'
activesupport (5.1.6) lib/active_support/core_ext/time/zones.rb:64:in `use_zone'
browser-timezone-rails (1.0.1) lib/browser-timezone-rails.rb:15:in `set_time_zone'
activesupport (5.1.6) lib/active_support/callbacks.rb:117:in `block in run_callbacks'
activesupport (5.1.6) lib/active_support/callbacks.rb:135:in `run_callbacks'
actionpack (5.1.6) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (5.1.6) lib/action_controller/metal/rescue.rb:20:in `process_action'
actionpack (5.1.6) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
activesupport (5.1.6) lib/active_support/notifications.rb:166:in `block in instrument'
activesupport (5.1.6) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (5.1.6) lib/active_support/notifications.rb:166:in `instrument'
actionpack (5.1.6) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (5.1.6) lib/action_controller/metal/params_wrapper.rb:252:in `process_action'
activerecord (5.1.6) lib/active_record/railties/controller_runtime.rb:22:in `process_action'
actionpack (5.1.6) lib/abstract_controller/base.rb:124:in `process'
actionview (5.1.6) lib/action_view/rendering.rb:30:in `process'
actionpack (5.1.6) lib/action_controller/metal.rb:189:in `dispatch'
actionpack (5.1.6) lib/action_controller/metal.rb:253:in `dispatch'
actionpack (5.1.6) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (5.1.6) lib/action_dispatch/routing/route_set.rb:31:in `serve'
actionpack (5.1.6) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (5.1.6) lib/action_dispatch/journey/router.rb:33:in `each'
actionpack (5.1.6) lib/action_dispatch/journey/router.rb:33:in `serve'
actionpack (5.1.6) lib/action_dispatch/routing/route_set.rb:844:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/rack/agent_hooks.rb:30:in `traced_call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/rack/browser_monitoring.rb:32:in `traced_call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
warden (1.2.7) lib/warden/manager.rb:35:in `catch'
warden (1.2.7) lib/warden/manager.rb:35:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rack (2.0.4) lib/rack/etag.rb:25:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rack (2.0.4) lib/rack/conditional_get.rb:38:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rack (2.0.4) lib/rack/head.rb:12:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rack (2.0.4) lib/rack/session/abstract/id.rb:232:in `context'
rack (2.0.4) lib/rack/session/abstract/id.rb:226:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/cookies.rb:613:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
activerecord (5.1.6) lib/active_record/migration.rb:556:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
activesupport (5.1.6) lib/active_support/callbacks.rb:97:in `run_callbacks'
actionpack (5.1.6) lib/action_dispatch/middleware/callbacks.rb:24:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/executor.rb:12:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rollbar (2.15.5) lib/rollbar/middleware/rails/rollbar.rb:24:in `block in call'
rollbar (2.15.5) lib/rollbar.rb:145:in `scoped'
rollbar (2.15.5) lib/rollbar/middleware/rails/rollbar.rb:22:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
rollbar (2.15.5) lib/rollbar/middleware/rails/show_exceptions.rb:22:in `call_with_rollbar'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
railties (5.1.6) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.1.6) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.1.6) lib/active_support/tagged_logging.rb:69:in `block in tagged'
activesupport (5.1.6) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.1.6) lib/active_support/tagged_logging.rb:69:in `tagged'
railties (5.1.6) lib/rails/rack/logger.rb:24:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
request_store (1.4.1) lib/request_store/middleware.rb:19:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/request_id.rb:25:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rack (2.0.4) lib/rack/method_override.rb:22:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rack (2.0.4) lib/rack/runtime.rb:22:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
activesupport (5.1.6) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rack-rewrite (1.5.1) lib/rack/rewrite.rb:24:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/executor.rb:12:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
actionpack (5.1.6) lib/action_dispatch/middleware/static.rb:125:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
rack (2.0.4) lib/rack/sendfile.rb:111:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
railties (5.1.6) lib/rails/engine.rb:522:in `call'
newrelic_rpm (5.0.0.342) lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
puma (3.11.3) lib/puma/configuration.rb:225:in `call'
puma (3.11.3) lib/puma/server.rb:624:in `handle_request'
puma (3.11.3) lib/puma/server.rb:438:in `process_client'
puma (3.11.3) lib/puma/server.rb:302:in `block in run'
puma (3.11.3) lib/puma/thread_pool.rb:120:in `block in spawn_thread'

This is the part which is repeating in the stack trace:这是在堆栈跟踪中重复的部分:

activesupport (5.1.6) lib/active_support/callbacks.rb:422:in 'block in inverted_lambda' activesupport (5.1.6) lib/active_support/callbacks.rb:422:in 'block in reverse_lambda'

activesupport (5.1.6) lib/active_support/callbacks.rb:177:in 'block (2 levels) in halting_and_conditional' activesupport (5.1.6) lib/active_support/callbacks.rb:177:in 'block (2 levels) inhalting_and_conditional'

activesupport (5.1.6) lib/active_support/callbacks.rb:177:in 'each' activesupport (5.1.6) lib/active_support/callbacks.rb:177:in 'each'

activesupport (5.1.6) lib/active_support/callbacks.rb:177:in 'all?' activesupport (5.1.6) lib/active_support/callbacks.rb:177:in 'all?'

activesupport (5.1.6) lib/active_support/callbacks.rb:177:in 'block in halting_and_conditional' activesupport (5.1.6) lib/active_support/callbacks.rb:177:in 'block inhalting_and_conditional'

activesupport (5.1.6) lib/active_support/callbacks.rb:507:in 'block in invoke_before' activesupport (5.1.6) lib/active_support/callbacks.rb:507:in 'block in invoke_before'

activesupport (5.1.6) lib/active_support/callbacks.rb:507:in 'each' activesupport (5.1.6) lib/active_support/callbacks.rb:507:in 'each'

activesupport (5.1.6) lib/active_support/callbacks.rb:507:in 'invoke_before' activesupport (5.1.6) lib/active_support/callbacks.rb:507:in 'invoke_before'

activesupport (5.1.6) lib/active_support/callbacks.rb:130:in 'run_callbacks' activesupport (5.1.6) lib/active_support/callbacks.rb:130:in 'run_callbacks'

activesupport (5.1.6) lib/active_support/callbacks.rb:827:in '_run_validate_callbacks' activesupport (5.1.6) lib/active_support/callbacks.rb:827:in '_run_validate_callbacks'

activemodel (5.1.6) lib/active_model/validations.rb:405:in 'run_validations!' activemodel (5.1.6) lib/active_model/validations.rb:405:in 'run_validations!'

activemodel (5.1.6) lib/active_model/validations/callbacks.rb:114:in 'block in run_validations!' activemodel (5.1.6) lib/active_model/validations/callbacks.rb:114:in 'block in run_validations!'

activesupport (5.1.6) lib/active_support/callbacks.rb:131:in 'run_callbacks' activesupport (5.1.6) lib/active_support/callbacks.rb:131:in 'run_callbacks'

activesupport (5.1.6) lib/active_support/callbacks.rb:827:in '_run_validation_callbacks' activesupport (5.1.6) lib/active_support/callbacks.rb:827:in '_run_validation_callbacks'

activemodel (5.1.6) lib/active_model/validations/callbacks.rb:114:in 'run_validations!' activemodel (5.1.6) lib/active_model/validations/callbacks.rb:114:in 'run_validations!'

activemodel (5.1.6) lib/active_model/validations.rb:335:in 'valid?' activemodel (5.1.6) lib/active_model/validations.rb:335:in 'valid?'

activerecord (5.1.6) lib/active_record/validations.rb:65:in 'valid?' activerecord (5.1.6) lib/active_record/validations.rb:65:in 'valid?'

It's a race condition.这是一个竞争条件。 I think you can only have 1 inverse_of since scan will call device and vice versa.我认为你只能有 1 inverse_of 因为 scan 会调用设备,反之亦然。

I've got the solution, although I don't exactly understand why it was working till now.我已经找到了解决方案,虽然我不完全理解为什么它到现在为止都在工作。 Originally there was the below validation in the Scan model (as I posted earlier):最初在 Scan 模型中有以下验证(正如我之前发布的):

  with_options unless: @photo.present? do
    validates :reading, presence: true
    validates :reading, numericality: true
    validates :reading_date, presence: true
  end

In irb I managed to localize the error to this validation part.在 irb 中,我设法将错误本地化到此验证部分。 After refactoring the @photo.present?重构@photo.present? to a new method and calling that method in the validation, the problem is solved:到一个新方法并在验证中调用该方法,问题就解决了:

  with_options unless: :has_photo? do
    validates :reading, presence: true
    validates :reading, numericality: true
    validates :reading_date, presence: true
  end

  def has_photo?
    @photo.present?
  end

According to the document :根据文件

:unless option: :unless选项:

Specifies a method, proc or string to call to determine if the validation should not occur.指定要调用的方法、过程或字符串,以确定是否不应进行验证。 The method, proc or string should return or evaluate to a true or false value.方法、proc 或 string 应返回或评估为 true 或 false 值。

But, your model Scan have unless: @photo.present?但是,您的模型Scanunless: @photo.present? :

with_options unless: @photo.present? do
  validates :reading, presence: true
  ...
end

That will lead to unexpected exceptions.这将导致意外异常。 In order to solve this issue, we should use any one of them below:为了解决这个问题,我们应该使用以下任何一种:

# Option 1:
with_options unless: proc { |scan| scan.photo.present? }

# Option 2:
with_options unless: 'photo.present?'

# Option 3:
with_options unless: :photo_present?

private

def photo_present?
  photo.present?
end

在我的情况下,由于命名错误,我遇到了类似的错误,请考虑检查名称是否会干扰 rails 内部的某些内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM