Rails Controller - Execute Action Only If the a Rails Ujs Method Inside Succeed (Mutually Dependent Methods)

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 good js.erb file

    format.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



Leave a reply



Submit