Rails controller - execute action only if the a Rails UJS method inside succeed (mutually dependent methods)
So the transaction will only rollback if an error is thrown. If an unhandled error is thrown, your application will crash and it will show a 500 error in some way.
In order to display the response to the user, on success or error, you will need to render something. So you don't want to prevent the respond_to
block from executing. One way to handle this would be to set a flag via an instance variable.
def deal_modal
begin
Deal.transaction do
update_user_table
update_userdeal_table
end
@success = true
rescue
@success = false
end
# show_modal_message
respond_to do |format|
format.js
end
end
Then in deal_modal.js.erb
<% if @success %>
showModalMessage("Here is your result <variable and all>");
<% else %>
showModalMessage("There was a problem");
<% end %>
EDIT:
Dealing with connection issues is definitely tricky and there isn't really one ideal solution. I would generally let the database continue uninterrupted and let it return either a success or failure on it's own time. For lengthy transactions, you can use a gem like delayed_job or sidekiq to process the action in the background and let the rails controller return a response saying "...pending..." or something. Unless you're using websockets on the frontend, this means continually polling the server with ajax requests to see if the background process is complete.
Rails controller - execute action only if the two methods inside succeed (mutually dependent methods)
If you are using ActiveRecord
, you could move your methods into the model and perform them in a transaction
block.
class DealsController < ApplicationController
def example_action
// 'user' would have to be defined, or you could work with it as a class method in some way
user.make_the_deal
end
end
class User < ActiveRecord::Base
def make_the_deal
transaction do
update_user_table
update_userdeal_table
end
end
def update_user_table
end
def update_userdeal_table
end
end
You don't necessarily have to put in your model to do this, you can just do:
User.transaction do
update_user_table
update_userdeal_table
end
in your controller. But it's recommended to put transactions in the model.
Prevent database action if Rails UJS (ajax) returns an Error or Timeout
I saw a similar issue on how Heroku suggests you handle timeout in its environment, but I don't think it will work for your case scenario, because your timeout has nothing to do with long running server side processing.
When your controller finishes its job, there is no way to know that the http request has succeeded or not if the client failed to receive the response after the request. I believe it's because the HTTP Protocol is stateless.
That being said, you could try others approaches. The more straightforward I can think of is: persist information to show the same data to the user next time he try to visualize the content or when the connection is reestablished (not counting as a new click).
Executing a conditional method only one time for a callback with multiple methods. Rails
Encapsulation is the one of the easiest way that you can choose to overcome this situation.
Just wrap your methods in another one, then it will only check this_happens?
one time.
class MyModel < ApplicationRecord
after_update :combine_methods, if: :this_happens?
#some custom methods
private
def combine_methods
method_1
method_2
method_3
end
def this_happens?
# a condition that returns true or false here
end
end
Want to call method that will execute everytime, when visitor visit my app rails
You were doing right, you should define this method in ApplicationController only and call that in before_action
. like:
class ApplicationController < ActionController::Base
before_action :get_ip
def get_ip
if request.remote_ip == '127.0.0.1'
# Hard coded remote address
'123.45.67.89'
else
request.remote_ip
end
end
end
get_ip
method will call every time as soon as request hits to ApplicationController
or any action of any controller inherited from ApplicationController
.
What's the best way to do UJS in rails when you have a re-usable widget?
I'd not recommend using UJS for frontend apps: server shouldn't take care of client side business. I agree it's useful and clean but it lacks performance and thus should be kept for backend stuff (RJS will move into a gem, see here: http://weblog.rubyonrails.org/2011/4/21/jquery-new-default).
That said, back to the solutions you expose:
1) I think you won't need an extra controller, you'd just have to pass additional params in order to know from where to query came from. A
hidden_field
could do the trick. With this info, render the goodjs.erb
fileformat.js { if condition
render "create.js.erb"
else
render "create_2.js.erb"
end
}2) I'd go for it and return json but you'll face the same problem: knowing from where the request comes from.
DRY in UJS in rails
You can render a partial from within your js.erb using the following syntax:
<%= render :partial => "shared/alerts" %>
Just put your code above into a partial in the appropriate directory. In my above example, the file would be called _alerts.js.erb and you'd put the partial in a directory I called shared (which would be in your views directory), but you can choose whatever directory you deem appropriate.
Rails - How to stub a certain response time for a stubbed / fake http or ajax response
If you really want it to just wait for the timeout I believe you can use the Proc version of and_return and sleep for as long as you want the request to take
proxy.stub("http://127.0.0.1:59533/deals/dealname/ajaxrequest").and_return(
Proc.new { |params, headers, body|
sleep 11
{code: 200}
} )
also - rather than wait_for_ajax just pass the amount of time you expect the element to take to appear to the within
call
within('ul.messenger', wait: 11) do ...
Rspec/capybara - simulate switch from Online to offline within a test (webkit driver)
Assuming you're just checking window.naviagtor.onLine
to determine whether or not it is on/offline (not depending on any events or anything) and because you're using capybara-webkit
(won't work in selenium since FF won't let you overwrite navigator, not sure about poltergeist) you can just overwrite window.navigator
with the result you want to get. You'll also need to generate an error response for your ajax request, which you can do with puffing-billy
page.execute_script "window.navigator = { onLine: false }"
Related Topics
Rails "Template Is Missing" Error
Rails Form_For Never Invokes the Create Controller Action to Use Redirect_To
Tilt (Kramdown) Preventing Erb Processing When Rendering Markdown
Ruby, Value Bucketing, Beautify Code
Ruby: Sorting 2 Arrays Using Values from One of Them
Ruby: How to Remove Items from Array a If It's Not in Array B
How to Require Activerecord in Irb
Ruby on Rails - Helper Method - Undefined Method 'Log_In' in Ruby on Rails
Heroku Deplyoment Asset Precompiling Failed on Rails 6
Importing CSV as Test Data in Cucumber
Rails 3 Translations Within Models in Production
Devise 'Find_First_By_Auth_Conditions' Method Explanation
Nomethoderror on Section 5.7 of Rails Guide
Error Occurs When Trying to Install Homebrew on a MAC for Ruby on Rails
Adding Comment to Yaml Programmatically
How to Verify Pacts Against an API That Requires an Auth Token
How to Turn on SQL Debug Logging for Activerecord in Rspec Tests