Some reason my hget is not finding or returning a hash I set in a public method. I can't figure out why.
This is all in one controller that inherits from ApplicationController, which is where I define my redis initializer:
def redis
Thread.current[:redis] ||= Redis.new
end
Then in my controller I do this to set the hash:
def return_customer
email = params["email"]
customer = Customer.find_by(email: email)
credit_amount = customer.credit_amount.to_f
customer_data = {email: email, customer_id: customer.id, credit_amount: credit_amount}
redis.hset("shop:#{customer.shop.id}:customer", customer_data, customer_data.inspect)
render json: customer
end
Then finally I have this private method I use in other methods in the same controller, this is the part that's not working:
private
def get_customer_from_redis
shop = Shop.find_by(shopify_domain: params["shop"])
customer_info = redis.hget("shop:#{shop.id}:customer", customer_data)
eval(customer_info)
end
This is the error that's returned
TypeError (no implicit conversion of nil into String):
I'd recommend you rather than using .inspect use .to_json like this:
def return_customer
email = params["email"]
customer = Customer.find_by(email: email)
credit_amount = customer.credit_amount.to_f
customer_data = {email: email, customer_id: customer.id, credit_amount: credit_amount}
redis.set("shop:#{customer.shop.id}:customer", customer_data.to_json)
render json: customer
end
And then in your private method
def get_customer_from_redis
shop = Shop.find_by(shopify_domain: params["shop"])
customer_info = redis.get("shop:#{shop.id}:customer", customer_data)
JSON.parse(customer_info) if customer_info
end
Related
I have a Private and a Third party inspection. After creating private inspection record automatically I need to create a third party Inspection. So that I have to call the create_history method from controller again with different params
class HomesController < BaseController
def create_history
#<ActionController::Parameters {"request_type"=>"Private", "user_id"=>"25" "requested_at"=>"Oct 28, 2022","private_inspection_type_id"=>"23780"} permitted: true>
inspection_request = #home.inspection_requests.new(inspection_request_history_params)
inspection_request.save
if inspection_request.get_paired_inspection.present?
inspection_request_history_params = {request_type: "Third Party", third_party_inspection_id: inspection_request.get_paired_inspection.id, status: inspection_request.status, user_id: inspection_request.user_id, requested_at: inspection_request.requested_at }
create_history
end
end
def inspection_request_history_params
params.require(:inspection_request).permit(:request_type, :user_id, :requested_at, :performed_at, :private_inspection_type_id, :third_party_inspection_id)
end
When i tried calling create_history method by passing different params like this I'm not getting the params . Any help is appreciatable
I think it's better if you put inspection_request.save on different method
class HomesController < BaseController
def create_history
inspection_request = create_inspection_requests(inspection_request_history_params)
if inspection_request.get_paired_inspection.present?
create_inspection_requests({
request_type: "Third Party",
third_party_inspection_id: inspection_request.get_paired_inspection.id,
status: inspection_request.status,
user_id: inspection_request.user_id,
requested_at: inspection_request.requested_at
})
end
end
private
def create_inspection_requests(attributes)
inspection_request = #home.inspection_requests.new(attributes)
inspection_request.save
return inspection_request
end
def inspection_request_history_params
params.require(:inspection_request).permit(:request_type, :user_id, :requested_at, :performed_at, :private_inspection_type_id, :third_party_inspection_id)
end
end
I'm writing some mobile otp validation service and below is my service class
require 'nexmo'
class NexmoServices
def initialize api_key = nil, api_secret = nil, opts = {}
api_key = api_key || Rails.application.secrets.nexmo_api_key
api_secret = api_secret || Rails.application.secrets.nexmo_secret_key
#nexmo_client = Nexmo::Client.new(
api_key: api_key,
api_secret: api_secret,
code_length: 6
)
#brand = 'CryptoShop'
end
def send_verification_code opts
#nexmo_client.verify.request(number: opts[:number], brand: #brand)
end
def check_verification_code opts
#nexmo_client.verify.check(request_id: opts[:request_id], code: opts[:verification_code])
end
def cancel_verification_code opts
#nexmo_client.verify.cancel(opts[:request_id])
end
end
in the controller i'm calling the service methods like below
class NexmoController < ApplicationController
def send_verification_code
response = NexmoServices.new.send_verification_code params[:nexmo]
if response.status == '0'
render json: response.request_id.to_json
else
render json: response.error_text.to_json
end
end
def cancel_verification_code
response = NexmoServices.new.cancel_verification_code params[:nexmo]
if response.status == '0'
render json: response.to_json
else
render json: response.error_text.to_json
end
end
end
I have read that usually there will be call method inside service class and controller will call that. service method call will take care of the rest.
My case im instantiating service objects for all the methods if you see my controller(NexmoService.new).
is it correct??? I want to know the best practise must be followed in this scenario.
Thanks,
Ajith
I'm trying to pass parameters(useremail,costprojects) from one controller action to another.
Here is the controller code:
def pdfemail
costprojects = Costproject.find(params[:costproject_ids])
useremail = current_user.email
CostprojectsController.delay.pdfemail2(params: { useremail: useremail, costprojects: costprojects })
redirect_to :back
flash[:notice] = 'An Email containing a PDF has been sent to you!'
end
def self.pdfemail2
#useremail = params[:useremail]
#costprojects = params[:costprojects]
...
But, I get:
wrong number of arguments (1 for 0)
The delay projects shows:
object: !ruby/class 'CostprojectsController'
method_name: :pdfemail2
args:
- :params:
:useremail: somebody#gmail.com
:costprojects:
- !ruby/ActiveRecord:Costproject
attributes:
id: 8
...
Thanks for the help!
If you want to pass some params while redirecting to another action, use the ActionController::Parameters:
def search
redirect_to :index, params: { query: params[:q] }
end
http://api.rubyonrails.org/classes/ActionController/Base.html
In my Invitations controller I call on a method in my model:
if abc.nil?
generate_username
end
The method is included in the Invitation model file:
def generate_username
self.username = rand(10000000..99999999).to_s
while Invitation.where( "lower(username) = ?", username.downcase ).first
self.username = rand(10000000..99999999).to_s
end
end
And in my Seeds file I have the line:
10.times do |n|
...
user = User.first
username = Invitation.generate_username
...
user.active_relationships.create!( ...,
username: username,
...)
end
Upon seeding I get the error below, referring to the username = line. Does anyone have an idea why this is the case and what I can do about it?
NoMethodError: undefined method `generate_username' for #<Class:0x00000009a2ab80>
You have an instance method, but you're trying to call it on a class. Use the method properly.
10.times do |n|
...
user.generate_username
...
user.active_relationships.create!( ...,
username: user.username,
...)
end
I've built a volunteer tracking application with a phone-text user interface using the Twilio API. I don't need a view so my controller contains this code:
class TwilioController < ApplicationController
include TwilioHelper
def sms_receive
user = User.find_or_create_by(phone_number: params[:From])
text = Text.create(user_id: user.id, body: params[:Body].capitalize, date: DateTime.now)
activity_log = ActivityLog.new(user_id: user.id, phone_number: "xxx-xxx-#{user.last_four_digits}", text_id: text.id)
args = {user: user, text: text, activity_log: activity_log, options: params}
volunteer_manager = VolunteerHandler.new(args)
replies = volunteer_manager.process
replies.each {|reply| text_response(reply, args[:options])}
end
def text_response(reply, args)
account_sid = ENV['ACCOUNT_SID']
auth_token = ENV['AUTH_TOKEN']
client = Twilio::REST::Client.new account_sid, auth_token
client.account.messages.create(:body => reply, :to => args[:From], :from => args[:To])
render nothing: true and return
end
end
A user will send a multi command string (i.e. 'In with American Red Cross'). In this case two commands will execute 'In' and 'with American Red Cross'. These commands return an array of strings such as ['Thank you for volunteering', 'Would you like the American Red Cross to keep in contact with you for future volunteering opportunities?']. This array is what local variable replies points to.
If I take off the render nothing:true and return code then I get the error: ActionView::MissingTemplate Missing template twilio/sms_receive
I can create the unnecessary view and solve my problem, but this doesn't seem like the best solution.
Any and all help is greatly appreciated. Thank you.
As replies is an array which is iterating over text_response its executing render nothing: true and return multiple times, which is cause of error you are facing.
Try getting render statement out of the loop.
class TwilioController < ApplicationController
include TwilioHelper
def sms_receive
user = User.find_or_create_by(phone_number: params[:From])
text = Text.create(user_id: user.id, body: params[:Body].capitalize, date: DateTime.now)
activity_log = ActivityLog.new(user_id: user.id, phone_number: "xxx-xxx-#{user.last_four_digits}", text_id: text.id)
args = {user: user, text: text, activity_log: activity_log, options: params}
volunteer_manager = VolunteerHandler.new(args)
replies = volunteer_manager.process
replies.each {|reply| text_response(reply, args[:options])}
render nothing: true and return
end
def text_response(reply, args)
account_sid = ENV['ACCOUNT_SID']
auth_token = ENV['AUTH_TOKEN']
client = Twilio::REST::Client.new account_sid, auth_token
client.account.messages.create(:body => reply, :to => args[:From], :from => args[:To])
end
end