rails 将参数或变量传递给多个控制器操作

rails pass params or variable to multiple controller actions

我有一个显示多个 "principals" 的下拉菜单,当用户选择主体并点击提交时,表单将主体 ID 参数传递给控制器​​操作。

问题是我需要在多个控制器中使用该参数值。

我的观点

  <div class="row">
    <div class="col-sm-12 button-wrapper">
      <%= form_tag(principal_analytics_path, method: 'get', class: 'form-inline justify-content-center') do %>
        <%= select_tag 'prid', options_from_collection_for_select(Principal.all, :id, :name), :prompt => "Select Principal", class: "form-control wrapper-space" %>
        <%= submit_tag "Search", class: 'btn btn-primary wrapper-space', :name => nil %>
      <% end %>
      <%= link_to "Clear", principal_analytics_path, class: "text-danger" %>
    </div>
  </div>

控制器动作

一旦我获得选定的主体 "books",我就需要一种将 @pri_books 变量从一个控制器传递到另一个控制器的方法。或者只是将“params[:prid]”传递给多个控制器操作的方法。我不知道该怎么做。也许是将变量从一个控制器传递到另一个控制器的函数?

  # displays graphs about principals.
  def principal_analytics

    @months_back = 12

    if params[:prid].present?
      # takes a principals id as a parameter.  
      # @months_back will determine how many months are shown in the chart.
      @pri_books = Book.principal_books(params[:prid], @months_back)  
    end

    respond_to do |format|
      format.html 
      format.js {}
      format.json { render json: {success: true}}
    end    
  end

您可以使用从控制器返回的数据来填充隐藏的表单元素 (hidden_field)。这些字段会将它们的值作为 params/data 提交给表单的操作,就像任何其他表单元素一样。注意:这是不安全的,很容易被用户操纵,所以如果担心这一点,请不要使用此方法。

或者,您可以将这些数据存储在 Rails' session 变量中。该会话在服务器中维护,可用于跨多个请求存储数据。请注意,要正确执行此操作,您应该确保有一个明智的方法来使会话数据过期或删除,以避免 (1) 保留比您需要的更多的数据,以及 (2) 混淆用户体验,他们期望一个新的空白表单但是之前多次点击填充的数据。

我最终让它工作的方法是制作一个 class 级别变量 @@class_variable 然后将其设置在接收参数的控制器操作中,然后我可以在其他控制器操作中使用这些参数.

虽然不确定这是否是正确的方法,但它确实有效。

# class level variable outside of any action
 @@principals_books = nil

    # displays graphs about principals.
      def principal_analytics

        @months_back = 12

        if params[:prid].present?
          # takes a principals id as a parameter.  
          # @months_back will determine how many months are shown in the chart.
          @pri_books = Book.principal_books(params[:prid], @months_back) 

          # set the data from the local instance variable to the class variable
          @@principals_books = @pri_books 
        end

        respond_to do |format|
          format.html 
          format.js {}
          format.json { render json: {success: true}}
        end    
      end

    def another_action
      @local_variable = @@principals_books
      @local_variable.do_something
    end

使用会话变量,这就是它们的用途...

session[:prid] = params[:prid]

你甚至可以在你的 ApplicationController 中设置一个方法,在你需要的时候给你本金...

class ApplicationController < ActionController::Base
  def current_principal
    principal.find_by(id: session[:prid])
  end
end

现在只需在需要的地方使用current_principal。 (如果您还没有选择,它将是 nil