Why is code inside model running without being asked, and how to run it on link click only?

I have this link in the view:

      <%= link_to "Pay in PayPal", @order.paypal_url(edit_order_url, payment_notification_url), class: "btn btn-success" %>

And this in the model:

     class Order < ActiveRecord::Base      def paypal_url(return_url, notify_url)         # ... Do stuff         self.update_attribute(:payment_in_process, true)         # Do more stuff...       end

When I visit the view, the model gets its attribute updated. I do not want this. I only want the attribute updated if the link is clicked.

Know how to accomplish this?

Hi

nanaya wrote in post #1183942:

Hi

     class Order < ActiveRecord::Base      def paypal_url(return_url, notify_url)         # ... Do stuff         self.update_attribute(:payment_in_process, true)         # Do more stuff...       end

When I visit the view, the model gets its attribute updated. I do not want this. I only want the attribute updated if the link is clicked.

You call the method in the view, thus the method is run. Nothing more, nothing less.

Nanaya, what can I do to only update the attribute when the link is clicked?

Separate out the code that generates the url from the code that updates the database. Then run the update in the action that is called when the link is clicked.

Colin

Colin Law wrote in post #1183944:

Colin Law wrote in post #1183944:

     class Order < ActiveRecord::Base      def paypal_url(return_url, notify_url)         # ... Do stuff         self.update_attribute(:payment_in_process, true)         # Do more stuff...       end

When I visit the view, the model gets its attribute updated. I do not want this. I only want the attribute updated if the link is clicked.

Know how to accomplish this?

Separate out the code that generates the url from the code that updates the database. Then run the update in the action that is called when the link is clicked.

Colin

Colin, there's no action called when the link is clicked, it just follows the URL generated by the method.

Well that is what you need to fix. If you need to do something to the database then you need to call an action in your application that does whatever it is you want to do. If necessary you can then redirect to your external url.

Are you a beginner with Rails? If so then I suggest that before going further you work right through a good tutorial such as railstutorial.org (which is free to use online), that will show you the basics of Rails.

Colin

Colin Law wrote in post #1183946:

want this. I only want the attribute updated if the link is clicked.

follows the URL generated by the method.

Well that is what you need to fix. If you need to do something to the database then you need to call an action in your application that does whatever it is you want to do. If necessary you can then redirect to your external url.

Are you a beginner with Rails? If so then I suggest that before going further you work right through a good tutorial such as railstutorial.org (which is free to use online), that will show you the basics of Rails.

Colin

Managed to solve this a while ago :slight_smile:

I created an action for the link which generates and follows the link, then when it gets back from it (PayPal), it updates the database.

  post 'orders/:id/pay', to: 'orders#start_payment_process', as: 'start_payment_process'

    <%= link_to "Pagar en PayPal", start_payment_process_path, class: "btn btn-success", method: :post %>

  def start_payment_process     @order = current_order     @order.update_attribute(:payment_in_process, true)     redirect_to @order.paypal_url(edit_order_url, payment_notification_url)   end

  def edit     # ... Some code     if @order.payment_notifications.any? && @order.payment_in_process       @order.update_attribute(:payment_in_process, false)     end   end

Thanks!