0

My show action:

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

There can be many different filters taking place in here whether with Ransacker, with the params[:limit] or others. At the end I have a subset of profiles.

Now I want to tag all these profiles that are a result of the search query.

Profiles model:

def self.tagging_profiles
  #Some code
end

I'd like to create an action within the same controller as the show that will execute the self.tagging_profiles function on the @profiles from the show action given those profiles have been filtered down.

def tagging
  @profiles.tagging_profiles
end

I want the user to be able to make a search query, have profiles in the view then if satisfied tag all of them, so there would be a need of a form

UPDATE:

This is how I got around it, don't know how clean it is but here:

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]

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

   private
   def tag_profiles(names)
     @profiles.tagging_profiles
   end

In my view, I created a form calling to self:

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

Is this the best way to do it?

4
  • Could you be more specific with your question? Commented Jun 18, 2014 at 18:54
  • Have you tried passing @profiles.pluck(:id) via sessions? You could also pass the information in a hidden form on the page, or via a link_to button that the user clicks to trigger the next action. Google "rails passing variables between controllers" and you'll get lots of answers, many of them on SO. Commented Jun 18, 2014 at 19:07
  • Your question is not clear. Do you want to implement a function that will tag all profiles contained in @profiles? Will you always do this tagging process each time the show action is executed? Commented Jun 18, 2014 at 19:08
  • I guess what I am asking is that I want the user to be able to make a search query, have profiles in the view then if satisfied tag all of them, so there would be a need of a form. Commented Jun 18, 2014 at 19:10

2 Answers 2

0

Rails public controller actions correspond always to a http request. But here there is just no need for 2 http requests. A simple solution would be just creating to private controllers methods filter_profiles(params) and tag_profiles(profiles) and just call them sequentially.

You can also extract this problem entirely to a ServiceObject, like this:

  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 

As processing 30,000 records is a time consuming operation, it would make sence to perform it outside of the rails request in background. This structure will allow you to delegate this operation to a sidekiq or delayed_job worker with ease

Sign up to request clarification or add additional context in comments.

4 Comments

You are also doing a lot of data manipulation in the controller instead of the model.
How can I tag with no requests but only with one request and a form?
I guess i've got your problem. Your first show the filtered data and then you want to tag it, rigtht?
In that case. You should perform the search twice. First time, when showing the profiles and second time, when tagging them. You can render the search params as hidden fields into the tagging form or you just save them in flash. On tagging form submit, you then do, what i've described in the answer
0

Instance Variables

If you want to "share" variable data between controller actions, you'll want to look at the role @instance variables play.

An instance of a class means that when you send a request, you'll have access to the @instance variable as long as you're within that instance of the class, I.E:

#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

This means if you wish to use the data within your controller, I would just set @instance variables, which you will then be able to access with as many different actions as you wish

--

Instance Methods

The difference will be through how you call those actions -

#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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.