timpone
timpone

Reputation: 19929

changing the value of a global variable in rails

I'm prototyping an app and want to have a global variable that I can hit an endpoint that toggles the global variable $current_status. I have:

  def toggle_status
     $current_status=false if $current_status.nil?
     $current_status=!$current_status
     r={}
     r[:current_status]=$current_status
     render json:r.to_json
  end

and in application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  $current_status
end

but hitting /toggle_status always returns false. Why isn't assigning a bool to what it isn't changing this value? I'm aware something like this should be in db but just prototyping

edit 1

I just created this in lib/

class Jt
  @cur
  def self.cur
    @cur
  end

  def self.cur=val
    @cur=val
  end
end

and updated the controller to:

  def toggle_status
     Jt.cur=!Jt.cur
     r={}
     r[:current_status]=Jt.cur
     render json:r.to_json
  end

Upvotes: 0

Views: 1363

Answers (3)

Vasfed
Vasfed

Reputation: 18444

Your first snipper does not work because != is a comparison operator, not assignment

Second may not work due to code reloading (Jt class instance is not guaranteed to be the same for other request unless cache_classes is on, but in development you usually always want it off, because otherwise any code changes require server restart to take effect), simple way to have a non-reloaded class - put it in a initializer

For prototyping you also may try thread-local storage for this task: Thread.current[:foo] = 1234

Upvotes: 0

Holger Just
Holger Just

Reputation: 55718

Your toggle code doesn't actually toggle anything. It appears you expect this line to "toggle" the contents of the $current_status variable.

$current_status!=$current_status

However, the != operator doesn't assign anything but it is a comparison operator. In your case, it returns always false based on your query whether $current_status is equal to not $current_status.

What you want to use instead is probably

$current_status = !$current_status

As for your software design, global variables are generally frowned upon in Ruby (and Rails) as are all other kinds of globally mutable state. Use proper classes and objects instead to encapsulate your state and behaviour into more manageable structures. Using global variables, you will shoot yourself in the foot some day and you will have a very hard time to find out what is actually happening. You should try to avoid this :)

Upvotes: 1

Simone Carletti
Simone Carletti

Reputation: 176352

You can't use a global variable in this way in such app and there are several reasons. I'll give you just one: depending on the webserver you use, the server may start different processes to handle the incoming web requests, and global variables can't be shared between these processes.

And in fact, it's not even a good idea to use a global variable at all.

If you want to persist a state, use a proper storage. Depending on how long the value should be persisted and who should be able to access it, you have plenty of choices:

  • database
  • file system
  • memory
  • cookie

Upvotes: 0

Related Questions