1

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 didn't implement them correctly
  • They were done inside the lambda scope
  • something else...

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.

Community
  • 1
  • 1
New Alexandria
  • 6,951
  • 4
  • 57
  • 77

1 Answers1

1

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
Holin
  • 1,191
  • 10
  • 10
  • Maybe this will work; I'll try soon. I think the issue may be that I'm not using a `Class` for the middleware, and am instead using the syntax I've given directly in my `config/application.rb`. – New Alexandria Dec 26 '15 at 02:42
  • 1
    I think you will have the same problem using a class, there is no real difference between a Class or block middleware. I think Rails use his own session system as it can be stored in a file, database, cookie, etc. and it can be signed or not. So I'm not really sure your can access the Rails session that way. If you don't need to persist the "no-index" information then using the env variable is not a problem, some Rails plugins use it that way. – Holin Dec 26 '15 at 07:54