call object in another controller before save rails 4 - ruby-on-rails-4

I have an object called reportapproval. I start the object in a form and before it is saved I want it to go thru a charge controller. If the charge does not go thru then it wont save the object but if it does then it will save.
I am trying to pass the unsaved object to the charge controller. How can I do this. Here are the 2 actions in their respective controller.
reportapproval_controller.rb
def create
#reportapproval = current_manager.reportapprovals.new(authorization_params)
if #reportapproval.valid?
if #reportapproval.manager_paying_report == true
flash[:notice] = "Please make payment before proceeding"
redirect_to new_managers_charge_path(id: #reportapproval_id)
charge_error = nil
end
end
end
charge_controller.rb
def create
# Amount in cents
#reportapproval = Reportapproval.new(session[:reportapproval_id])
#manager = current_manager
#amount = #reportapproval.manager_request_report_type
customer = Stripe::Customer.create(
:email => #manager.email,
:card => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
...
)
#reportapproval.report_paid = true
#reportapproval.save!
redirect_to managers_dashboard_path, :notice => "You have successfully ..."
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to managers_charges_path
end
end
How can I pass this object to the charge and then back to the reportapproval before saving to the DB. I am using mongoid btw.
Thanks in advance.

You can but you shouldn't do that. Save the Reportapproval with a flag to indicate that it hasn't been paid for yet. After the Stripe procedure went through remove the flag to allow the user full access.
Btw, this will also help you find out wether and how many user do stop during the Stripe procedure and not come back again.

Related

Crud operation "Delete" don't works in my first project in ruby on rails

I'm implementing in my first project the crud operation "delete", but the system take the command as a "get", whitout errors.
this is the controller:
class MoviesController < ApplicationController
def index
#movies = Movie.all
end
#GET /movies/:id
def show
id = params[:id]
#movie = Movie.find(id)
#render plain: 'show'+params[:id]
end
#POST /movies/
# skip_before_action :verify_autenticity_token:
def create
#movie = Movie.create!(params[:movie].permit(:title, :rating, :description, :realease_date))
flash[:notice] = "#{#movie.title} was successfully created."
redirect_to movies_path
end
#new
def new
end
def edit
id = params[:id]
#movie = Movie.find(id)
end
def update
id = params[:id]
#movie = Movie.find(id)
if #movie.update_attributes!(params[:movie].permit(:title,:rating,:realease_date))
flash[:notice] = "#{#movie.title} has been edited."
redirect_to movies_path
end
end
def destroy
id = params[:id]
#movie = Movie.find(id)
#movie.destroy
flash[:notice] = "#{#movie.title} has been deleted."
redirect_to movies_path
end
end
this is the view where is possible call "Delete" operation:
%h2 Details about #{#movie.title}
%ul#details
%li
Rating:
= #movie.rating
%li
Released on:
= #movie.realease_date#.strftime("%B %d, %Y")
%h3 Description:
%p#description= #movie.description
%h4 Reviews:
- if #movie.reviews.empty?
%p
No reviews for this movie...
-else
- #movie.reviews.each do |r|
- u = Moviegoer.find(r.moviegoer_id)
<b>#{r.vote}</b> (<i>#{Moviegoer.find(r.moviegoer_id).name}</i>) #{r.message} <br />
= link_to 'Add review', new_movie_review_path(#movie)
<br/><br/>
#{link_to 'Edit info', edit_movie_path(#movie)} - #{link_to 'Delete', movie_path(#movie), :method => :delete} - #{link_to 'Back to movie list', movies_path}
The problem probably is in the last line, because in server command line "Delete" isn't calls.
this is the server response (is the last GET that is execute when i press "Delete" on the browser) :
enter image description here
file routes.rb:
Rails.application.routes.draw do
resources :movies do
resources :reviews, only: [:new, :create, :destroy]
end
resources :moviegoers
root :to => redirect('/movies')
end
Result of command "rake routes":
Prefix Verb URI Pattern Controller#Action
movie_reviews POST /movies/:movie_id/reviews(.:format) reviews#create
new_movie_review GET /movies/:movie_id/reviews/new(.:format) reviews#new
movie_review DELETE /movies/:movie_id/reviews/:id(.:format) reviews#destroy
movies GET /movies(.:format) movies#index
POST /movies(.:format) movies#create
new_movie GET /movies/new(.:format) movies#new
edit_movie GET /movies/:id/edit(.:format) movies#edit
movie GET /movies/:id(.:format) movies#show
PATCH /movies/:id(.:format) movies#update
PUT /movies/:id(.:format) movies#update
DELETE /movies/:id(.:format) movies#destroy
moviegoers GET /moviegoers(.:format) moviegoers#index
POST /moviegoers(.:format) moviegoers#create
new_moviegoer GET /moviegoers/new(.:format) moviegoers#new
edit_moviegoer GET /moviegoers/:id/edit(.:format) moviegoers#edit
moviegoer GET /moviegoers/:id(.:format) moviegoers#show
PATCH /moviegoers/:id(.:format) moviegoers#update
PUT /moviegoers/:id(.:format) moviegoers#update
DELETE /moviegoers/:id(.:format) moviegoers#destroy
root GET / redirect(301, /movies)
rails_service_blob GET /rails/active_storage/blobs/:signed_id /*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage /direct_uploads(.:format) active_storage/direct_uploads#create
It's hard to say exactly what's going on without seeing the corresponding routes. You might try running rake routes to see what the available routes are.
Based on the comments in your controller, I'm guessing you probably have to do something like pluralize the path link_to 'Delete', movies_path(id: #movie.id), method: :delete, but that would only fix the problem if your resource routes are misconfigured.
In order for the link to work as you have it configured your route file would either have to contain resources :movies, or a specially configured route to map to the delete action.

Integration testing ActionMailer and ActiveJob

In the past, Rails 3, I've integrated action mailer testing with my Cucumber/Rspec-Capybara tests like the following example. With Rails 4, using the following doesn't seem to work.
I am able to see that the job is queued using enqueued_jobs.size. How do I initiate the enqueued job to ensure that the email subject, recipient and body are correctly being generated?
app/controllers/robots_controller.rb
class MyController < ApplicationController
def create
if robot.create robot_params
RobotMailer.hello_world(robot.id).deliver_later
redirect_to robots_path, notice: 'New robot created'
else
render :new
end
end
end
spec/features/robot_spec.rb
feature 'Robots' do
scenario 'create a new robot' do
login user
visit '/robots'
click_link 'Add Robot'
fill_in 'Name', with: 'Robbie'
click_button 'Submit'
expect(page).to have_content 'New robot created'
new_robot_mail = ActionMailer::Base.deliveries.last
expect(new_robot_mail.to) eq 'myemail#robots.com'
expect(new_robot_mail.subject) eq "You've created a new robot named Robbie"
end
end
I use the rspec-activejob gem and the following code:
RSpec.configure do |config|
config.include(RSpec::ActiveJob)
# clean out the queue after each spec
config.after(:each) do
ActiveJob::Base.queue_adapter.enqueued_jobs = []
ActiveJob::Base.queue_adapter.performed_jobs = []
end
config.around :each, perform_enqueued: true do |example|
#old_perform_enqueued_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_jobs
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true
example.run
ActiveJob::Base.queue_adapter.perform_enqueued_jobs = #old_perform_enqueued_jobs
end
config.around :each, perform_enqueued_at: true do |example|
#old_perform_enqueued_at_jobs = ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs
ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = true
example.run
ActiveJob::Base.queue_adapter.perform_enqueued_at_jobs = #old_perform_enqueued_at_jobs
end
end
This lets me tag features/scenarios with perform_enqueued: true if I want the jobs to actually execute.

Rails 4 - Loop through deeply nested params to prevent update of password field to blank

In an edit form, an existing password appears in the form as blank, which seems to be the default Rails behavior. I'm trying, however, to avoid the password (or in my case passwords) from being updated to blank if a new password isn't entered, similar to what is described here:
Rails Activerecord update saving unedited field as blank
The difference for me is that the password field is more deeply nested and there is more than one.
Basically what I have is a small bank transfer app where for every :transfer there are two :transfer_accounts, source and destination (transfer_accounts is a "has_many, through" join table for transfers and accounts) and both transfer accounts have an :account with a :password attribute.
My attempt was something like this at the top of the update action:
params[:transfer][:transfer_accounts_attributes].each do |k, v|
v[:account_attributes][:password].delete if v[:account_attributes][:password].empty?
end
which didn't work. Either password left blank is updated to blank.
How would I iterate through the params and prevent either or both passwords from updating if they are left blank?
Here is my controller:
class TransfersController < ApplicationController
def new
#transfer = Transfer.new
#transfer.transfer_accounts.build(account_transfer_role: 'source').build_account
#transfer.transfer_accounts.build(account_transfer_role: 'destination').build_account
#valid_banks = Bank.all.collect {|c| [c.name, c.id]} # available banks seeded in database
end
def index
#transfers = Transfer.all
end
def show
#transfer = resource
end
def create
#transfer = Transfer.new(transfer_params)
if #transfer.save
redirect_to transfers_path, notice: "Transfer Created"
else
redirect_to transfers_path, alert: "Transfer Not Created"
end
end
def edit
resource
#valid_banks = Bank.all.collect {|c| [c.name, c.id]} # available banks seeded in database
end
def update
if resource.update_attributes(transfer_params)
redirect_to transfers_path(resource), notice: "Transfer Updated"
else
redirect_to edit_transfer_path(resource), alert: "Transfer Not Updated"
end
end
def destroy
resource.destroy
end
private
def resource
#transfer ||= Transfer.find(params[:id])
end
def transfer_params
params.require(:transfer).
permit(:name, :description,
transfer_accounts_attributes:
[:id, :account_transfer_role,
account_attributes:
[:id, :bank_id, :name, :description, :user_name,
:password, :routing_number, :account_number
]
])
end
end
params[:transfer][:transfer_accounts_attributes].each do |k, v|
v[:account_attributes].delete(:password) if v[:account_attributes][:password].blank?
end
You have to call hash.delete, rather than delete the contents of the already blank value. Also .blank? is your friend, since that will take care of nil and == ''.

undefined method `model_name' for #<User:XXXXXXXX>

I have a dashboard containing 2 partials. One partial works fine and does what its suppose to (bill). The other partial is setup similar to bill but wont work(request). When I look at my log it shows that the tenant(user) is being queried, also, the 1st partial is queried but the 2nd partial doesn't query. when I went to my dashboard controller and changed the instance of the partial to (Request.new) it works but I can't seem to get it to work right thru the controller. I don't want to have the method in the model. I am using mongoid.
SO here is my render in the dashboard...
<%= render partial: "request", locals: {request: #request} %>
In the partial I have...
<%= form_for [:tenants, request] do |f| %>
And on the dashboard controller I have...
def show
#dashboard = current_tenant
#bill = current_tenant.bill || current_tenant.build_bill
#request = current_tenant.request || current_tenant.build_request
end
(if I change #request = Request.new it works fine but I know that's not right)
The bill partial works and the dashboard finds the tenant but I keep getting
"undefined method `request' for #
Any idea of what I am missing? I compared the bill controller to the request controller and I cant find any differences. When I put the Model.new into the dashboard controller it works but I know this isn't right, its as if the app wont recognize the Request controller...
The error is saying it doesn't recognize "request" method.
Also here is my controller for request...
class Tenants::RequestsController < ApplicationController
before_filter :authenticate_tenant!
def index
#requests = Request.all
end
def show
#request = Request.find(params[:id])
end
def create
if #request = current_tenant.create_request(authorization_params)
redirect_to tenants_dashboard_path, :notice => "#{request.manager_name} has been Authorized!"
else
redirect_to tenants_dashboard_path, :error => "#{request.manager_name} has NOT been Authorized, please try again."
end
end
def edit
end
def update
if current_tenant.request.update_attributes(authorization_params)
redirect_to tenants_dashboard_path, :notice => "You have approved #{request.manager_name} to review your report"
else
redirect_to tenants_dashboard_path, :notice => "#{request.manager_name} is NOT allowed to review your report"
end
end
def destroy
#request = Request.find(params[:request_id])
name = #request.name
if #request.destroy
flash[:notice] = "\"#{name}\" was successfully removed from your profile."
redirect_to #dashboard
else
flash[:error] = "There was an error deleting this managers access."
render :show
end
end
Well it looks like
current_tenant.request has an issue. That means that the method is not available. Assuming you're not trying to access the http request , then you have an issue with the request method.
So your issue is with how you defined the request method (maybe in your model). e.g. is it a class method or a instance method etc.
Without knowing your goal, that's the general answer I can give you. Creating a Request.new could be right depending on your goal, but if your goal is to call the request method, you must make it available to current_tenant
One controller shouldn't be calling your other controller as you have suggested...

Rails 4:register a person in my rails app through voice call verification

Can you please share that how can i make a outbound call to a person who want to register in my Rails 4 application and make a verification through his voice(in short i want to register a person in my rails app through voice call verification), Is that possible with twillo or suggest some other way to do it?
Please suggest the step by step or suggest some tutorial/doc/video
https://github.com/twilio/twilio-ruby
and
https://www.twilio.com/docs/quickstart/ruby/twiml
Call and ask for verification:
require 'twilio-ruby'
# build up a response
response = Twilio::TwiML::Response.new do |r|
r.Say 'hello there, enter verification code', :voice => 'alice'
r.Dial :callerId => '+14159992222' do |d|
r.Gather :numDigits => '5', :action => "/verify_code?id=#{id}", :method => 'get' do |g|
g.Say 'Verified thankyou.' if verified?
else
# hangup or set behaviour
end
end
end
end
def verify_code
#verification = Verification.where(verification_code: params[:id]).first
if #verification
#activate
else
# Handle errors
end
end
Finally in your model you'll need code that generates the verification code, and verifies if it is confirmed
class Verification < ActiveRecord::Base
before_create -> { self[:verification_code] = rand.to_s[2..5] }
end