在同一控制器Rails中的操作之间传递变量

时间:2014-06-18 18:52:06

标签: ruby-on-rails ruby-on-rails-4

我的表演行动:

def show
        # Multiple keywords

        if current_user.admin?
            @integration = Integration.find(params[:id])
        else            
            @integration = current_user.integrations.find(params[:id])
        end


        @q = @integration.profiles.search(search_params)
        @profiles = @q.result.where(found: true).select("profiles.*").group("profiles.id, profiles.email").includes(:integration_profiles).order("CAST( translate(meta_data -> '#{params[:sort_by]}', ',', '') AS INT) DESC NULLS LAST").page(params[:page]).per_page(20)
        @profiles = @profiles.limit(params[:limit]) if params[:limit]
end

无论是使用Ransacker还是使用params [:limit]或其他,都可以在这里发生许多不同的过滤器。最后,我有一个配置文件的子集。

现在我想标记所有这些搜索查询结果的配置文件。

个人资料模型:

def self.tagging_profiles
  #Some code
end

我希望在同一个控制器中创建一个动作,该动作将从show动作执行self.tagging_profiles上的@profiles功能,因为这些动态已被过滤掉。< / p>

def tagging
  @profiles.tagging_profiles
end

我希望用户能够进行搜索查询,在视图中包含配置文件然后如果满意标记所有这些,那么就需要表单

更新:

这就是我如何解决它,不知道它有多干净,但在这里:

def show             #多个关键字

        if current_user.admin?
            @integration = Integration.find(params[:id])
        else            
            @integration = current_user.integrations.find(params[:id])
        end


        @q = @integration.profiles.search(search_params)
        @profiles = @q.result.where(found: true).select("profiles.*").group("profiles.id, profiles.email").includes(:integration_profiles).order("CAST( translate(meta_data -> '#{params[:sort_by]}', ',', '') AS INT) DESC NULLS LAST").page(params[:page]).per_page(20)
        @profiles = @profiles.limit(params[:limit]) if params[:limit]

        tag_profiles(params[:tag_names]) if params[:tag_names]
end

   private
   def tag_profiles(names)
     @profiles.tagging_profiles
   end

在我看来,我创建了一个调用自我的表单:

<%= form_tag(params.merge( :controller => "integrations", :action => "show" ), method: :get) do %>
        <%= text_field_tag :tag_names %>
        <%= submit_tag "Search", class: "btn btn-default"%>
       <% end %>

这是最好的方法吗?

2 个答案:

答案 0 :(得分:0)

Rails公共控制器操作始终对应于http请求。但是这里不需要2个http请求。一个简单的解决方案就是创建私有控制器方法filter_profiles(params)tag_profiles(profiles),然后按顺序调用它们。

您也可以将此问题完全解压缩到ServiceObject,如下所示:

  class ProfileTagger
    attr_reader :search_params          

    def initialize(search_params)
      @search_params = search_params
    end

    def perform
      search
      tag
    end

    def tag
     #tag found profiles
    end

    def search
     @profiles = #do the search
    end 
  end 

由于处理30,000条记录是一项耗时的操作,因此可以在后台执行rails请求之外的操作。此结构允许您轻松地将此操作委派给sidekiq或delayed_job worker

答案 1 :(得分:0)

Instance Variables

如果您想在控制器操作之间“共享”可变数据,则需要查看角色@instance variables播放。

类的实例意味着当您发送请求时,只要您在该类的实例中,您就可以访问@instance变量,IE :

#app/controllers/your_controller.rb
Class YourController < ApplicationController
   before_action :create_your_var

   def your_controller
      puts @var
   end

   private

   def create_your_var
       @var = "Hello World"
   end
end

这意味着如果您希望使用控制器中的数据,我只需设置@instance variables,您就可以根据需要使用多种不同的操作来访问

-

实例方法

区别在于你如何称呼这些行动 -

#app/controllers/your_controller.rb
Class YourController < ApplicationController
   def action
      #-> your request resolves here
      method #-> calls the relevant instance method
   end

   private

   def method
      #-> this can be called within the instance of the class
   end
end