New Alexandria
New Alexandria

Reputation: 7324

How can session info be passed between Rack 1.6+ and Rails 4.2+

I have read this question in some length, particularly this answer. This may be the same, too. I'm of the opinion that they are for an older version of rack+rails than I am using now.

I have a rack middleware:

config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
  r301 %r{^/reviews/company/(\d+)}, lambda { |match, _rack_env|
    company = Company.find_by_id(match[1])

    case company.reviews.count
    when 0
      "/company-reviews"
    when 1..3
      "/#{company.slug}/reviews/"
      # set no_index = true
    else
      "/#{company.slug}/reviews/"
      # set no_index = false
    end
  }
end

Within those non-zero clauses, I would like to set a no_index variable to be available in the controller.

module ApplicationHelper
  def application_meta_tags
    @application_meta_tags.merge(
      'no-index' => no_index_from_rack
    )
  end
end

Inside of the lambda in rack, I can do

request = Rack::Request.new(env)
request.session['no-index']=true

but it doesn't not appear in the controller scope.

request.session.keys
# [
#     [0] "session_id",
#     [1] "_csrf_token"
# ]

Since similar-looking answers have not worked, I wonder is this due to

I am open to altogether-different strategies to pass data between rack and rails.

Update

I am currently using 'ENV' and/or Rails.configuration but this is not session-based, and I must un-set the variable after every use. Even then, I suspect that a race condition may nip me.

Is this a place I can set headers that will be later available to Rails? I'm trying to understand what is the right concept for passing data between these apps / contexts.

Upvotes: 1

Views: 398

Answers (1)

Holin
Holin

Reputation: 1241

You definitely should not use ENV or Rails.configuration because they are global variables, and as you know global variables are evil. And as you said you will have race conditions.

If there is no reason to store the no_index boolean in the session, you should directly use the env variable :

Your middleware :

class Middleware
  def initialize(app)
    @app = app
  end

  def call(env)
    env['app.no_index'] = true
    @app.call(env)
  end
end

Your controller/view :

class Controller
  def new
    env['app.no_index'] # is true
  end
end

Upvotes: 1

Related Questions