Let's say that at the beginning of the run I set a variable in the session like this:
session[:plan_id]= "plan_id_number_in_string"
later in the run I want to ovewrite that value, meaning:
session[:plan_id]= "plan_id_2_number_in_string"
I'm having issues with this, can this be done?
Related
the question is very simple:
How do I create a conditional breakpoint in byebug about a variable assignment? This is more an event than a condition. But how would you proceed if you do not know where in the code the assignment could happen?
Watching a variable in step by step manner isn't forthbringing. I would need to watch it, until some arbitrary value is assigned to the identifier.
I only know that an Identifier is somewhere in the Rails program, maybe even in the initialization process, is assigned a value to. I don't know when or what. The "what" is what I want to find out. Do you think there is a debugging solution?
Thanks
von Spotz
E.g. if you know that the variable starts off as nil
byebug unless x.nil?
Then scatter that statement around your code wherever that variable is in scope and you suspect it may be changed. Or if you want to restrict it to a certain operation or loop, set a global variable where you want to start looking like
$enable_byebug = true if name == 'foo'
do(something)
...
byebug if !x.nil? && $enable_byebug
This is one of the few contexts where I'm happy to use global variables.
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
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 :)
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
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
I have a Ruby on Rails server for a web application.
I am wondering if instance variables in Ruby are shared on different requests. Here is my problem:
Bob makes a Get request to my ruby server; it first initiates a instance variable #x and then its request is processed for a while.
In the meantime, Alice makes another Get request that initiates a instance variable #x.
At the end of Bob's process, the variable #x is looked at. Will it have the value given by Bob or Alice?
What if Bob and Alice are the same person that quickly makes the same request twice in a row? Will the first request see the value initiated by the second request at the end of its process?
Edit: this happens when config.cache_classes is set to true and from my experiments, it doesn't concern controllers' instance variables but it do concern librairies. Here is what I have done. When an http request arrives, I set an instance variable #x to a random value and save it in a variable x. I sleep for a while and then I compare #x and x. When I launch several requests at the same time, I sometime find different values when doing the comparison. However, this mismatch doesn't happen in controllers but it does in librairies. Does it means that the controllers are not cashed but librairies are when config.cache_classes = true ?
#x is not a global variable, it's an instance variable.
No, controller instance variables are not shared between requests.
Rails 4 is the first version to be multi-threaded by default - you shouldn't run into variable concurrency issues with earlier versions unless you explicitly turned threading on in the config (config.threadsafe!).
You can still have database-related concurrency issues in single-threaded Rails: If, for example, you read from a field at the start of a request, perform some calculation on that value and then write it back.
In multi-threaded Rails you can have concurrency problems with global or class variables too, as these are stored in shared memory space. Global variables are defined with the dollar symbol $x and class variables are defined with two at symbols ##x - both have their uses but there are usually better ways to pass data around.
I want to initialize a variable in rails and use it in a controller's action, but the variable should have a fixed value when the server starts. I have tried defining it inside a controller's action and it get's the same initialized value for every request. For example, i want to initialize a date.now and have the same date after 15 days also.
Update
I am implementing a coming soon page in which a timer is shown 15 days from now. If i implement it in a action inside a controller, it shows new date every time the action is invoked.
Please Help
If you want to create a CONSTANT in rails then you can simply put it into the initializer file. For eg, create a file name constants.rb inside initializer:
#config/initializers/constants.rb
TEST_VALUE = 10
And to access this CONSTANT from your controller, just call for TEST_VALUE. for eg,
#controllers_path/some_controller.rb
.....
def some_def
#value = TEST_VALUE # this will be enough to fetch the constants.
end
But, make sure you restart your server after changing the intializer.
You're looking to create a constant, which is basically a variable which doesn't change its value
You'd typically set these with initializers:
#config/initializers/your_initializer.rb
YOUR_CONSTANT = your_date
To maintain a persistent date, you'll have to give some more context on what you're using it for. It will be difficult to create this each time Rails loads (how to know which Time.now to use), so giving us more info will be a good help
You can also use an opposite approach. Assuming you should know the date when the new feature comes (for example 2014-04-04 18:00) you can just find a number of seconds left till the target date:
#seconds_left = Time.parse('2014-04-04 18:00').to_i - Time.now.to_i
then pass it to client side and implement a timer. So you'll just need to store a string representation of a target date.
Obvious disadvantage of this approach is that you should adjust that target time each time you want to introduce a new feature.
Right now, my program has a tweeting system. I want to be able to save the current tweet whenever there's an update, and save the last tweeted thing. Then, every 10 minutes, a rake script runs and the tweet gets sent out. This is to prevent multiple tweets. The problem is that I have no way of saving the last tweeted phrase. I've tried using something like:
MY_VARS = {}
in application.rb, and then using MY_VARS[:old] = MY_VARS[:current], but that keeps being overridden. I also tried using the caching in rails, specifically:
Rails.cache.write("current", myTweet)
But that gets overridden to nil everytime the script runs. Does anyone know how I should be doing this?
A good place is to store it at some file, since it's a worker script it's not that important to be fast, in your case