【问题标题】:Accessing a variable of one method in another in ruby on rails在 ruby​​ on rails 中访问另一种方法的变量
【发布时间】:2022-01-14 10:24:25
【问题描述】:

我在访问方法的特定变量时遇到问题 A ,在另一种方法中说 B 在控制器中。对象(变量)的大小太大,因为它包含进行的服务调用的结果..我的用例就像从下拉框中选择一个选项一样,它重定向到控制器中的方法B,并且应该解析相同的对象(变量)。如何在其他方法中访问变量?

我尝试存储在 cookie 中,但由于大小太大,我收到了 Cookie 溢出异常。我没有使用数据库。所以我想使用 memcache 是行不通的。还尝试将其存储为视图中的隐藏字段,并通过 ajax 调用将其值作为数据传递。但我把它当作一个字符串。试图将数据类型指定为 json 和其他几种方式..但没有用..使用 @@var 也可以工作..不知道为什么..

代码:

关于下拉菜单的变化:

$(document).ready(function(){
    $('#filter_service').change(function() {
        $.ajax({type: "GET",
            url: "/device_troubleshootings/query_operation",
            data: { filter_service: $('# filter_service').val()},
        });
    });
});

服务调用:

def log_results
  //Service call
  @get_log_results = LogQueryService.client.get_logs(Com::Amazon::Logqueryservice::DeviceSerialNumberQuery.new(:search_text => @ search , :index => 'dms', :index_type => '_all', :from_time_stamp =>  @from_time_stamp, :to_time_stamp => @to_time_stamp))
  @dsn_result = @get_log_results.logs_result_obj_list
end

在这里,我尝试在“/device_troubleshootings/query_operation”方法中访问@dsn_result 对象。

请建议我访问变量的方法。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 variables cookies


    【解决方案1】:

    MVC

    我认为您对 Rails 应该如何工作感到困惑

    请记住,Rails(它只是一个 Ruby 框架)是基于 "MVC" programming pattern 构建的。这意味着每次您向 Rails 应用程序发送 request 时,都必须由单个 controller#action 处理,然后您将允许您从模型中提取相关数据

    您遇到的问题是您尝试加载多个控制器方法,并将相同的数据传递给两者。这可能适用于 Ruby,但不适用于 Rails(Rails 是无状态的):

    --

    型号

    处理此类设置的正确方法是为您的应用程序创建另一个请求,该请求将加载另一个controller#action,允许您访问所需的数据

    如上面的 MVC 图所示,每次向 Rails 发送请求时,基本上都是一个请求。这意味着除非您将数据保存在 cookie 中,否则您需要从模型中加载数据。

    您遇到的问题是您试图将整个数据集存储在系统的front-end 中。这个问题非常糟糕,不仅效率低下,而且完全违背了 MVC 模式。

    您最好将所需的最小数据集存储在前端(ids 或类似的),然后您可以通过 ajax 将其发送到您的控制器;从

    构建一个新的数据集

    --

    类变量

    你提到你试图声明一些@@class variables 无济于事。这样做的问题是类变量只能用于类的实例

    如前所述,由于 Rails 无状态,类变量不会在请求之间持续存在(它们怎么会?)。考虑到您一直在尝试使用 cookies 来存储您的数据,我想您已经知道这一点

    解决这个问题的方法是每次从模型中重建数据(如上所述)


    解决方案

    你的解决方案是“去无状态”

    方法如下:

    1. Method AMethod B 视为完全独立的“操作”
    2. 使用这些操作时,您需要考虑在两者之间传递的最小数据段
    3. 要加载Method B,您需要从浏览器发送一个新请求(就像您以前从未加载过Method A一样)

    您的method_a 可以以“标准”方式处理:

    #config/routes.rb
    resources :your_controller do
       collection do
          get :method_a
          get :method_b
       end
    end
    

    这意味着您可以相对简单地加载method_a

    #app/controllers/your_controller.rb
    Class YourController < ApplicationController
       def method_a
          @get_log_results = LogQueryService.client.get_logs(Com::Amazon::Logqueryservice::DeviceSerialNumberQuery.new(:search_text => @ search , :index => 'dms', :index_type => '_all', :from_time_stamp =>  @from_time_stamp, :to_time_stamp => @to_time_stamp))
          @dsn_result = @get_log_results.logs_result_obj_list
       end
    end
    

    如您所知,@dsn_result 不会持续到下一个请求。

    有两种方法可以解决此问题(设置 CONSTANT -- 如果您从 API 中提取,这将为您提供一次调用 -- 或使用 before_action 为尽可能多的操作设置变量根据需要)。我会为你详细说明:

    #app/controllers/your_controller.rb
    Class YourController < ApplicationController
        before_action :set_log_data
    
        def method_a
        end
        
        def method_b
        end
       
        private
    
        def set_log_data
           @get_log_results = LogQueryService.client.get_logs(Com::Amazon::Logqueryservice::DeviceSerialNumberQuery.new(:search_text => @ search , :index => 'dms', :index_type => '_all', :from_time_stamp =>  @from_time_stamp, :to_time_stamp => @to_time_stamp))
           @dsn_result = @get_log_results.logs_result_obj_list
        end
    end
    

    如果您从自己的数据集中提取数据(使用模型),这将起作用,但是,在您的情况下,更好的方法可能是设置一个常量(当然,考虑到您不这样做)不希望数据改变):

    #config/initializers/dsn_result.rb
    get_log_results = LogQueryService.client.get_logs(Com::Amazon::Logqueryservice::DeviceSerialNumberQuery.new(:search_text => @ search , :index => 'dms', :index_type => '_all', :from_time_stamp =>  @from_time_stamp, :to_time_stamp => @to_time_stamp))
    DSN_RESULT = get_log_results.logs_result_obj_list
    

    【讨论】:

      【解决方案2】:

      在我的情况下,我用全局变量 $my_global_var 解决了

      所以我的文件看起来像这样

      routes.rb

      Rails.application.routes.draw do
        resources :pages
        root 'pages#index'
      
        post 'pages/test'
      end
      

      pages_controller.rb

      class PagesController < ApplicationController
      
          def firstaction 
              $my_global_var = "My global var"
              puts $my_global_var
          end 
      
          def secondaction 
              puts $my_global_var
          end 
          
      end
      
      

      index.html.erb

      <%= button_to 'Test', pages_test_path, method: :post %>
      

      【讨论】:

        猜你喜欢
        • 2014-09-14
        • 2020-02-20
        • 2019-07-31
        • 1970-01-01
        • 1970-01-01
        • 2013-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多