Rails 4 - Remove attributes from an already filtered Active Record query

618 Views Asked by At

In one of my ruby on Rails 4 controller, I have a method that injects data necessary to a View.

The data needed vary between the data needed by the html and the data needed by the javascript. I am using gon to inject the data into the js scripts.

My app works fine but gon is injecting in the HTML (FYI in a script just below the body tag) too much data as I only need for Gon/Javascript 2 of the 5 attributes needed by the HTML view. (Reason for wishing that: As I load a lot of objects, the difference in bytes for the HTML file is very significant)

def inject_deal_steps_data
      # Used in html view     
      @steps = @deal.steps.select(:attribute1,
                                  :attribute2,
                                  :attribute3,
                                  :attribute4,                                             
                                  :attribute5). order(attribute4: :asc)

      # Used in js file
      gon.push( { deal_steps: @steps } ) if @steps
    end

I tried using methods such as unscope like below but it did not work.

def inject_deal_steps_data
          # Used in html view     
          @steps = @deal.steps.select(:attribute1,
                                      :attribute2,
                                      :attribute3,
                                      :attribute4,                                             
                                      :attribute5). order(attribute4: :asc)

          # Used in js file
          gon.push( { deal_steps: @steps.unscope(:attribute1,:attribute3,:attribute4 } ) if @steps
        end

I don't want to create another new selection like below as it creates a new request/hit on the database.

@steps = @deal.steps.select(:attribute1,
                                      :attribute2,
                                      :attribute3,
                                      :attribute4,                                             
                                      :attribute5). order(attribute4: :asc)
gon.push( { deal_steps: @deal.steps.select(:attribute2,:attribute5) } ) if @deal.steps

I want to re-use for GON the same @steps created for the HTML but remove 3 attributes from it.

1

There are 1 best solutions below

0
On BEST ANSWER

You can use as_json to control what will be exposed by the to_json. gon calls to_json internally, in order to convert ruby object to javascript object and exposes it to the view.

Try the following:

def inject_deal_steps_data
  # Used in html view     
  @steps = @deal.steps.select(
    :attribute1,
    :attribute2,
    :attribute3,
    :attribute4,                                             
    :attribute5
  ).order(attribute4: :asc)

  # Used in js file
  gon.push({ 
    deal_steps: @steps.as_json(except: [:attribute1,:attribute3,:attribute4])
  }) if @steps
end

Review as_json for more information.