Reputation: 25
I am developing a rails app. Most of the parts work fine, but I got one weird problem when I tried to calculate the time an user used to edit and submit one form.
I thought it would be good to do it in the following order: 1. in the controller "edit" method, record the time the user start to see the form. 2. in the "update" method, record the submit time, then do the math and get how long the user had spent on the form.
class Test
@@start_time = 0
@@end_time = 0
def edit
@@start_time = Time.now
end
def update
@@end_time = Time.now
time_used = @@end_time - @@start_time
puts time_used.to_i
end
end
The code above actually works fine while running on my own developing computer, the output is what I expected. But when I upload the code to the production environment(multicore cpus), sometime the output is right, sometime it is not. I debugged the code and found in some case, the @@start_time is set to 0 when submitting the form. I am confused what was going on, maybe I just misused the @@ for the variable. Please help me out, any idea would be appreciated, thanks.
Edit: The problem is solved by adding a virtual attribute to the model as hinted by Vishal. In addition, I added a hidden field in the submit form, and in the strong parameter part added the corresponding parameter to allow it to be passed from edit to update method.
Upvotes: 0
Views: 64
Reputation: 6455
You're using class variables that can interfer with each other. Your Test
class will only ever have one class variable called @@start_time
associated with it.
This means if another user sees the form, they will reset the @@start_time for every user currently on it.
To prevent this, use instance varaibles. When a new user sees the form, they will make a new instance variable that is tied to their instance of the class, rather than the class itself. This will allow users to have different start and end times.0
All you need to do is change every @@
to @
. So instead of @@start_time', try
@start_time` throughout your code, and the same for end_time.
Upvotes: 0
Reputation: 828
Your solution will create conflicts when more than two users try to edit simultaneously, So basically what idea I have is:
Add one virtual attribute in your model edit_start_time
You don't need attribute for endtime
because it can be directly fetched by Time.now
at any time.
Set edit_start_time
value in edit
method like:
@model.edit_start_time = Time.now.utc #you can use any
In update
method directly calculate edit time like:
total_update_time = Time.now.utc - @model.edit_start_time.utc
If you are unaware of how to create virtual attributes then there are so many questions on StackOverflow as well as docs. I am not explaining how to do it here because its the different topic.
All the best
Upvotes: 1