简体   繁体   中英

Pass an object from one controller action to another

I have a request object that I want to pass to my charges_controller . I can pass it in to the new action but after that new action is called I need that same request object passed to the create object in the same charges_controller . I can not get it. Here is the initial request_controller action passing the request_id to the charges controller.

class Users::RequestsController < ApplicationController
before_filter :authenticate_user!

def create
  @user = current_user
    if @request = @user.request.create!(authorization_params)
      if @request.user_paying == true
        redirect_to new_users_charge_path(id: @request)
      else
        redirect_to users_dashboard_path
      end
    else
      redirect_to users_dashboard_path, :error => "There is something wrong and your request has not been submitted."
    end
end````

It then passes it to the new method in the charges controller. Here is my charges controller.

class Managers::ChargesController < ApplicationController
  before_filter :authenticate_user!

  def new
    @request = Request.find(params[:id])
    @user = current_user
    @amount = @request.user_amount
  end

  def create
    # Amount in cents
    @request = Request.find params[:request_id]
    @user = current_user
    @amount = @request.user_amount

customer = Stripe::Customer.create(
  :email => @user.email,
  :card  => params[:stripeToken]
)

charge = Stripe::Charge.create(
  :customer    => customer.id,
  :amount      => @amount,
  :description => 'Manager Paid Report',
  :currency    => 'usd'
)
@request.report_paid = true
@request.save!
redirect_to managers_dashboard_path, :notice => "You have succesfully requested a pre-paid report from #{@reportapproval.tenant_last_name}."

rescue Stripe::CardError => e
  flash[:error] = e.message
  redirect_to managers_charges_path
end
end

I can get the request info into the charges/new.html view. But when I create the charge the request is not found. How can I pass the request to the create action?

Here is the new view...

<h4>Total Payment Due: <%= number_to_currency(@amount.to_i/100.0) %>
  <%= form_tag users_charges_path do %>
    <%= hidden_field_tag :request_id, @request.id %>
<br />
    <script src="https://checkout.stripe.com/checkout.js"   class="stripe-button"
        data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
        data-description="Payment"
        data-amount="<%= @amount %>"
        data-locale="auto" >
        </script>
  <% end %>

Controllers simply respond to HTTP requests - there is no way to forward a request internally in Rails. This is a very conscious design decision.

If you need to stash data in between requests you would either save it in the database, the session or some sort of caching mechanism like Memcached/Redis.

Most commonly in Rails you stash data in the database and pass ID's or other unique identifiers in the request parameters.

If you need to pass the id to the "Request" object you would either pass it in the request url or in the request body in the case of PUT/PATCH/POST .

So in your case you need to ensure that the #new action either posts to:

post "/managers/charges/:request_id"

Or that the form includes

<%= hidden_field_tag 'request_id', @request.id %>

PS

Request although not technically a reserved word is a really bad name for a model since it will eventually cause conflicts and confusion with ActionDispatch::Request especially if you use the controller instance variable @request .

As you can see from the my answer above it gets confusing as h*ll since the word request is allready has a very specific connotation in web development.

The same applies to Response .

Use PaymentRequest or any other synonym .

Assuming you have a form in the charges/new view, you can set the request_id using a hidden form field:

<%= hidden_field_tag :request_id, @request.id %>

You should add the line above between <%= form_for ... do |f| %> <%= form_for ... do |f| %> and <% end %> .

In that example, you were assuming the create action would somehow have a request_id passed in automatically. Rails doesn't do that, in every request you need to explicitly provide all the information for the controller to process that request.

I hope that helps! ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM