How to use the variable in one action to another action - ruby

In the ruby controller, I have two methods in the same controller.
class NotificationsController < ApplicationController
def first
variable_one = xxxx
end
def second
// do something
end
end
I want to use the variable one in the method first, and use it in the method two. I tried to assign the variable one to a session hash. session[:variable_one] = variable_one, and access it in the method two. But it turns out the session[:variable_one] in the method two is nil. These two methods don't have the corresponding views, so I cannot add a link_to and pass parameters. The method one cannot be set as before_action as well.
Could you please have some suggestions on this problem? Thanks so much.

The issue that session is stored via cookie, and therefore it is specific to one device. So, you will have one session between the rails app and your frontend, and another session betweeen the rails app and Twilio (probably the Twilio session will reset between each request). Basically, they're totally separate contexts.
Possibly you could figure out how to pass the information along via Twilio - see https://www.twilio.com/docs/voice/how-share-information-between-your-applications - but as a general-purpose workaround, you could just store the column on the database.
First, make a migration to add the column:
add_column :users, :my_variable, :string
Set this value in the first endpoint:
def first
current_user.update my_variable: "xxxx"
end
Then read it from the second:
def second
# first you would need to load the user, then you can read the value:
my_variable = current_user.my_variable
# you could set the db value to nil here if you wanted
current_user.update my_varible: nil
end

Related

How to make my session variable available to the models with Thread variable?

I have a sessions variable that stores the group id. I have set a before filter in my application controller that sets the session[:group_id]
# In my application controller
before_filter :save_request_path
def save_request_path
if request.params[:group_id]
session[:group_id]= request.params[:group_id]
end
end
At this point I am trying to access this session variable inside a model. I have seen an example of doing it for current_user using Thread variable. I do not seem to understand such example however https://www.zorched.net/2007/05/29/making-session-data-available-to-models-in-ruby-on-rails/.
How would I do this using the thread variable in my specific case ?
If you really want to use a thread variable, I'd recommend using request_store, which avoids concurrency issues by using thread-local variables.
This is how you'd store the value:
def save_request_path
if request.params[:group_id]
RequestStore.store[:group_id] = request.params[:group_id]
end
end
And this is how you access it:
RequestStore.store[:group_id]

Create an object from within a script Ruby

I am attemping to create an object from a class. But the objects will be created when they are needed.. Code below a bit hard to explain
incoming_message = #message sent though inter webs
class Repeater
def initialize(username, ip)
#repeat incoming message to back to ip
end
end
incoming_message = Repeater.new(user, ip)
Now I can't do that Becuase incoming_message is not a constant.
How would I get around this?
EDIT:
To clear things up a bit. I do need to use this class to create multiple objects with diffrent names. The repeater is for a chat server where an incoming message from 1 user is taken in then sent back out all of the clients connected. Each new client that connects would have a object created with that specific IP address so that messages from others can be send to the client.
It would take in messages from the other users by everyone sending to the server on the same port read the message then write to clients what it received...
I hope this helped sorry for all the confusion :)
If you want to maintain some kind of global class-level state, you should define a class-level accessor on Repeater that you can assign your repeating message to.
class Repeater
class << self
attr_accessor :incoming_message
end
def initialize(username, ip)
# repeat Repeater.incoming_message to back to ip
end
end
Repeater.incoming_message = "what"
Repeater.new(user, ip)
You need to use some parsing + serialization . Can they wire an already serialized/marshalled string?
1) convert the ruby code to yaml or json
2) use the json or yaml load method like myobj = YAML.load(new_yaml_string)
or
save it in another file called input and do a
require 'input'
create object of repeater

Rails 4 update Type when migrating to Single Table Inheritance

Rails 4.0.4, Ruby 2.1.2
I want to use STI like so:
User < ActiveRecord::Base
Admin < User
But currently I have:
User < ActiveRecord::Base
Info < ActiveRecord::Base
So I changed my models, and then start writing my migration. In my migration, I first add a column to allow STI:
add_column :users, :type, :string
Then I want to update the Users currently in the database to be Admin
# Place I'm currently stuck
Then I move all my Info records into the Users table
Info.all.each { |info| User.create(name: info.name, email: info.email) }
Everything seems to work except turning the previous Users into Admins. Here are some things I've tried:
# Seems to work, but doesn't actually save type value
User.each do |user|
user.becomes!(Admin)
user.save! # evaluates to true, doesn't have any errors
end
# Seems to work, but doesn't actually save type value
# I've also tried a combo of this one and the above one
User.each do |user|
user.type = "Admin"
user.save! # evaluates to true, doesn't have any errors
end
User.each do |user|
user = user.becomes!(Admin)
user.save! # evaluates to true, doesn't have any errors
end
# Seems to work, but doesn't actually save type value
User.each do |user|
user.update_attributes(type: "Admin")
end
Each time the local user variables seems to have the correct type ("Admin"), along with save evaluating to true, but when I check Admin.count or check Users type value, it is always nil. I know you're not supposed to change them, but this is just to migrate the data over to STI and then I'll be able to start creating Users or Admin with the proper class.
At the very least I think Rails should raise an error, set an error or somehow let the developer know it's failing the save calls.
It turns out that while update_attributes doesn't work for type (I haven't researched why yet), update_column does work.
So the migration simply becomes:
User.each do |user|
user.update_columns(type: "Admin")
end
The reason this works and other updates don't can probably be traced back to either callbacks or validations not being run. I have no callbacks that would prevent it, but maybe there are default Rails ones for type
http://apidock.com/rails/ActiveRecord/Persistence/update_columns
If you had more rows in the database User.each would become quite slow as it makes an SQL call for each user.
Generally you could use User.update_all(field: value) to do this in one SQL call but there is another reason to avoid this: if the User model is later removed the migration will no longer run.
One way to update all rows at once without referencing the model is to use raw SQL in the migration:
def up
execute "UPDATE users SET type = 'Admin' WHERE type IS NULL"
end

Subclass Rack::Throttle

i am reading about Rack::Throttle and i want to change the default client identifier from an IP to somethng else. The documentation says it can be done
The rate-limiting counters stored and maintained by Rack::Throttle are
keyed to unique HTTP clients.
By default, HTTP clients are uniquely identified by their IP address
as returned by Rack::Request#ip. If you wish to instead use a more
granular, application-specific identifier such as a session key or a
user account name, you need only subclass a throttling strategy
implementation and override the #client_identifier method.
I have no clue where to add that in, here is my current subclass for another method. Does anybody know how to do this? https://github.com/datagraph/rack-throttle
module Rack
module Throttle
class DailyRequests < Daily
def allowed?(request)
## Insert rules
super request
end
end
class HourlyRequests < Hourly
def allowed?(request)
## Insert rules
super request
end
end
class RequestInterval < Interval
def allowed?(request)
## Insert rules
super request
end
end
end
end
You should subclass one of the existing rack-throttle classes (probably either Rack::Throttle::Interval or Rack::Throttle::TimeWindow, whichever one more closely aligns with your needs) and override the #client_identifier method.
#client_identifier is passed one argument, request, which is a Rack::Request instance containing information passed in the incoming HTTP request and can be used to get information such as HTTP headers, cookies, path, and possibly other info depending on your app. The default implementation looks like this:
# #param [Rack::Request] request
# #return [String]
def client_identifier(request)
request.ip.to_s
end
Here's an example of subclassing Rack::Throttle::Interval to match requests on a query parameter such as ?user_id=<id>:
class UserThrottle < Rack::Throttle::Interval
def client_identifier(request)
request['user_id']
end
end
which you could use in a Rack application with:
use UserThrottle, :min => 100
Notice you can still pass options like :min to the Rack use statement, since it is just subclassing the existing throttle classes. And adopting this in a Rails app would just involve calling use in your application.rb file (see Rails on Rack).

Cannot access session array from view in Rails 3.1

So this one has me stumped; hopefully a kind soul can help me out. As part of logic to display certain buttons for users who have performed an action, I store the id of the object they manipulated in a session array called "prayed_for". (The unique part of this problem is that it deals with sessions and not an array persisted in a database.) In the show action of my controller, I evaluate whether of not the current id of the entry being requested is present in the session array "prayed_for". I assign this boolean value to the session variable #already_prayed_for. Below is the logic for that:
#already_prayed_for = (session[:prayed_for] ||= []).include? params[:id]
But here's the problem: I cannot evaluate this in my partial. For example if I attempt to evaluate the following (in HAML), where "entry" is a variable representing the entry at hand and "id" is it's id, which should be stored in the session "prayed_for" variable, it will always evaluate to false:
-if (session[:prayed_for] ||= []).include? entry.id
I've come to the conclusion that I may be evaluating something wrong in my partial when evaluating whether or not an id is present in a session array. Additionally this same concept worked perfectly in a controller action (but I can't use that solution this time around, it has to be evaluated in the partial) but it also failed in the ApplicationHelper. Any help in resolving this problem is much appreciated!
UPDATE:
Here's the code where I set the session in another action:
if #entry.save
(session[:prayed_for] ||= []) << params[:id]
end
params[:id] may be a String, while entry.id is a Fixnum. Verify that the objects you're comparing (via include?) are of the same type.
You might want to make a helper out of the logic you're using, for example:
def already_prayed_for?(entry_id)
(session[:prayed_for] ||= []).include? entry_id.to_i
end

Resources