lost session after redirect_to - ruby-on-rails

Newly added description: (sorry for not mentioning)
The ApplicationController.current_account is defined as:
class ApplicationController < ActionController::Base
class << self
def current_account
#current_account
end
def current_account=(value)
#current_account = value
end
end
=========
I encountered a strange performance in my current project, which is about session. The strange part is it was normal in Safari but failed in other browsers (includes chrome, firefox and opera).
There is a registration form for input of part of the key information (email, password, etc) and is submitted to an action called "create"
This is the basic code of create action:
#account = Account.new(params[:account])
if #account.save
ApplicationController.current_account = #account
session[:current_account] = ApplicationController.current_account
session[:account] = ApplicationController.current_account.id
email = #account.email
Mailer.deliver_account_confirmation(email)
flash[:type] = "success"
flash[:notice] = "Successfully Created Account"
redirect_to :controller => "accounts", :action => "create_step_2"
else
flash[:type] = "error"
flash[:title] = "Oops, something wasn't right."
flash[:notice] = "Mistakes are marked below in red. Please fix them and resubmit the form. Thanks."
render :action => "new"
end
Also I created a before_filter in the application controller, which has the following code:
ApplicationController.current_account = Account.find_by_id(session[:current_account].id) unless session[:current_account].blank?
For Safari, there is no any problem. But for the other browsers, the session[:current_account] does not exist and so produced the following error message:
RuntimeError in AccountsController#create_step_2
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Please could anyone help me?

1] don't write
ApplicationController.current_account
Just
current_account
2] in your application_controller
def current_account
session[:current_account]
end
3]
ApplicationController.current_account = #account
session[:current_account] = ApplicationController.current_account
session[:account] = ApplicationController.current_account.id
should be
session[:current_account] = #account
session[:account] = #account.id

Related

How to test destroy failure in ruby-on-rails

everyone.
I'm gonna test an active record object destroy failure but I've problems creating a failure situation.
I have a before_filter method called 'require_user_payment_info' which validates the #payment_info object before the delete method is called, so I can't create a 'bad' #payment_info object before the delete method is called.
Here's the require_user_payment_info method:
def require_user_payment_info
#payment_info = credit_card_model.slave.find_by_user_guid(user_guid)
if !#payment_info || #payment_info.user_guid != user_guid
redirect_to(:controller => 'store', :action => 'index') and return false
else
if((#payment_info.card_expires_year.to_i < Date.today.year) ||
((#payment_info.card_expires_month.to_i < Date.today.month) && (#payment_info.card_expires_year.to_i == Date.today.year)))
#payment_info.card_account_public = "" #clear this out so the user is forced to re-enter the credit card number
#payment_info.valid?
flash.now[:error] = t('ui_flash_errors.card_expired_error')
end
end
end
And the actual delete method:
def delete
# required to be called via a delete request
redirect_to :action => 'edit' and return if !request.delete?
if #payment_info.destroy
flash[:notice] = "Delete SUCCESSFUL"
redirect_to :action => 'new'
else
flash[:error] = "Delete failed"
redirect_to :action => 'edit'
end
Any ideas?
This is my solution:
def test_delete
payment_info = Factory.create(:payment_info, :user_guid=>#user.guid, :card_expires_month=>'04',
:card_expires_year=>(Date.today.year+2).to_s, :cardholder_city=>"test city",
:cardholder_state=>'NC', :cardholder_country=>'US', :cardholder_zip=>'27612')
PaymentInfo.any_instance.stubs(:destroy).returns(false)
delete(:delete, {}, #session)
assert_response(:redirect)
assert_equal false, assigns(:payment_info).blank?
assert_redirected_to({:controller=>'account', :action=>'edit'})
assert_equal flash[:error], "There was an error deleting your credit card information. Please try again."
end

Twilio sending error The requested resource /2010-04-01/Accounts//Messages.json was not found

going through this course to build ROR app and sending a twilio message to verify persons mobile number. I get the error" The requested resource /2010-04-01/Accounts//Messages.json was not found" found a previous question request however they did not have much code to review and he mentioned that he finally has it working mentioned he had a null variable of $sid and token; not sure what to verify. I tried both test and production sid and token #s from my acct. Thanks so much for your attention.
initailizer/twilio.rb
Twilio.configure do |config|
config.account_sid = ENV['TWILIO_ACCOUNT_SID']
config.auth_token = ENV['TWILIO_AUTH_TOKEN']
end
models/user.rb
def generate_pin
self.pin = SecureRandom.hex(2)
self.phone_verified = false
save
end
def send_pin
#client = Twilio::REST::Client.new
#client.messages.create(
from: '+15812345678',
to: self.phone_number,
body: "Your pin is #{self.pin}"
)
end
def verify_pin(entered_pin)
update(phone_verified: true) if self.pin == entered_pin
end
Application.yml
TWILIO_ACCOUNT_SID: '12345678901234567'
TWILIO_AUTH_TOKEN: '123434567890123456'
TWILIO_NUMBER: '+15878551234'
users controller
def update_phone_number
current_user.update_attributes(user_params)
current_user.generate_pin
current_user.send_pin
redirect_to edit_user_registration_path, notice: "Saved!"
rescue Exception => e
redirect_to edit_user_registration_path, alert: "#{e.message}"
end
def verify_phone_number
current_user.verify_pin(params[:user][:pin])
if current_user.phone_verified
flash[:notice] = "FYi Your phone number is verified"
else
flash[:alert] = "Cannot verify your phone number"
end
redirect_to edit_user_registration_path
rescue Exception => e
redirect_to edit_user_registration_path, alert: "#{e.message}"
end
private
def user_params
params.require(:user).permit(:phone_number, :pin)
end
I'm not sure but could you try this
def send_pin
account_sid = 'your-account-sid'
auth_token = 'your-auth-token'
#client = Twilio::REST::Client.new account_sid, auth_token
#client.messages.create({
from: '+15812345678',
to: self.phone_number,
body: "Your pin is #{self.pin}"
})
end

can not persist the new object between requests - RoR

In my application, I have a twitter and facebook login, however I need to prompt a password and email after they first register with twitter or facebook. I am using omniauth gems and my controller/user model looks like this:
//socials_controller.rb
def create
#render text: request.env['omniauth.auth'].to_yaml and return
#user = User.from_omniauth(request.env['omniauth.auth'])
if(#user.email == nil)
redirect_to patient_login_entry_url(#user)
elsif #user.confirmed
log_in #user
redirect_to #user
else
flash[:danger] = "Bir hata olustu."
redirect_to root_url
end
end
def login_entry
#patient = Patient.find(params[:id])
end
def update_social
#patient = Patient.find(params[:id])
if #patient.update_attributes(user_params)
SendVerificationEmailJob.perform_later #patient
flash[:success] = "Aktivasyon için #{#patient.email} adresinizi kontrol ediniz."
redirect_to root_url
else
flash[:danger] = "Bilgilerinizi kontrol edip tekrar deneyiniz."
redirect_to patient_login_entry_url(#patient)
end
end
and my from_omniauth method is:
//user.rb
has_secure_password
class << self
def from_omniauth(auth_hash)
if exists?(uid: auth_hash['uid'])
user = find_by(uid: auth_hash['uid'])
else
user = find_or_create_by(uid: auth_hash['uid'], provider: auth_hash['provider'], type: 'Patient')
user.location = get_social_location_for user.provider, auth_hash['info']['location']
if auth_hash.provider == 'facebook'
user.avatar = User.process_uri(auth_hash['info']['image'])
user.name = auth_hash['extra']['raw_info']['first_name']
user.surname = auth_hash['extra']['raw_info']['last_name']
user.email = auth_hash['extra']['raw_info']['email']
user.gender = auth_hash['extra']['raw_info']['gender']
elsif auth_hash.provider == 'twitter'
user.avatar = auth_hash['info']['image']
user.name = auth_hash['info']['name']
end
user.url = get_social_url_for user.provider, auth_hash['info']['urls']
user.save!
end
user
end
At the login_entry page, I simply prompt the email and password, and POSTing them to the update_social method.
However, as expected, my app throws the error "Password can't be blank", because has_secure_password validates its presence by default. So, I need to persist it between the requests since I can not save it without a password. How can I achieve this?
I tried to store the created object in session by using to_json method, and turning it into a hash between requests, however this time the profile picture I got from twitter/facebook did not persist (I'm using AWS S3 + Paperclip, the URL persists but there is no such image when I check it from the S3 console) so I think that solution was not good.

Set value to belongs_to attributes in rails create action

I'm trying to set the title of a Page in my create action.
I would need to page.translation.title = params[:page][:title]
def create
#page = Page.new(params[:page])
#page.translation.title = params[:page][:title]
if #page.save
redirect_to admin_pages_path
else
render :new
end
end
Also tried
#translation = #page.translation.build(title: params[:page][:title])
from the console when I run:
p = Page.last
p.translation.title
=> nil -----> right now after its created, title is nil.
p.translation.title = "foo"
=> "foo"
This is what I what in my create action. any help would be greatly
appreciated. Thank you.
Update:
I'm using this on a legacy application that's running on refinerycms 2.1.0.dev
Relevant code:
https://github.com/DynamoMTL/g-refinerycms/blob/244d4a89aef4ad31aed9c50a0ca4c8a2ffd3d1ac/pages/app/models/refinery/page_part.rb#L10
https://github.com/DynamoMTL/g-refinerycms/blob/244d4a89aef4ad31aed9c50a0ca4c8a2ffd3d1ac/pages/app/models/refinery/page.rb#L45-L49
https://github.com/DynamoMTL/g-refinerycms/blob/244d4a89aef4ad31aed9c50a0ca4c8a2ffd3d1ac/pages/app/models/refinery/page.rb#L11-L14
Solution
def create
#page = Refinery::Page.new(params[:page])
if #page.save!
#page.translations.create(slug: #page.slug,
title: params[:page][:title],
locale: params[:switch_locale])
flash.notice = t(
'refinery.crudify.created',
what: "'#{#page.title}'"
)
redirect_to admin_pages_path
else
render :new
end
end

Rescuing from Twitter Gem

I have a tweets_controller
#called when user submits twitter form
def message
unless current_user
session[:twitter_message] = params[:twitter_message] #sets the message from the form so it's available for send_tweet in tweet.rb after we pass through omniauth
redirect_to '/auth/twitter' #redirects to authorize via omniauth/twitter and create the user
else
#auth = Authorization.find_by_user_id(current_user)
Tweet.update_status(#auth, params[:twitter_message])
redirect_to edit_user_path(current_user), :notice => "Tweet sent."
end
end
I'm trying to rescue when the status update fails. I want to display a flash message to the user, but -- this is as far as I can seem to get:
def self.update_status(auth, msg)
#token = auth.token
#secret = auth.secret
#message = msg
#t = Twitter::Client.new
Twitter.configure do |config|
config.consumer_key = '[key]'
config.consumer_secret = '[secret]'
config.oauth_token = #token
config.oauth_token_secret = #secret
config.gateway = '[gateway_url]'
end
ret = #t.update(#message)
tweet ||= Tweet.create_from_response(ret, auth.id)
rescue Twitter::Error => e
logger.error "#{e.message}."
end
How do I get the error message so I can display it to my user through the controller?
You can create and throw a custom exception based on the application.
In app/lib/could_not_update_status_error.rb
class CouldNotUpdateStatusError < StandardError
end
Then in your model:
rescue Twitter::Error => e
logger.error "#{e.message}."
raise CouldNotUpdateStatusError.new("Could not update status")
And in your controller
else
begin
#auth = Authorization.find_by_user_id(current_user)
Tweet.update_status(#auth, params[:twitter_message])
redirect_to edit_user_path(current_user), notice: "Tweet sent."
rescue CoundNotUpdateStatusError => e
# Do error stuff
end
Another option would be to do rescue return false in your Twitter::Error clause and wrap the update_status call in an if statement, however Exceptions are a more robust solution.

Resources