Reputation: 19929
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
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
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
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
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:
Upvotes: 0