Rob Hughes
Rob Hughes

Reputation: 906

Ruby on rails. Create 'model' from inside another controller

I have a 'job site' where users can create jobs and other users can apply for them. Users need 'tokens' to create jobs, and when they have none left are redirected to a purchase tokens page. The token system works fine. I have set up a braintree form which works too, but doesn't create any tokens for the user. I want to create a new token(s) for the user when the transaction completes.

so far I have

routes.rb

resources :users do
resources :tokens
resources :transactions

Token.rb

class Token < ActiveRecord::Base
 belongs_to :user
end

Transactions.rb

 class Transaction < ActiveRecord::Base
  belongs_to :user
end

new token/payment form

    <form id="checkout" method="post" action="/transactions">
  <div id="payment-form"></div>
  <h2 class="mbs">Transaction</h2>
  <p> Payment formfor one gig </p>
  <%= form_tag transactions_path do%>
    <p>Please enter your payment details:</p>
    <div id="dropin"></div>
    <%=submit_tag "Pay €1.99", class: "button mt1" %>
  <%end%>
</form>

transactions_controller

 class TransactionsController < ApplicationController
before_action :find_user

  def new
  end


def create
    @result = Braintree::Transaction.sale(
              amount: 10,
              payment_method_nonce: params[:payment_method_nonce])
    if @result.success?
      @user = Token.build(params[:user_id => current_user.id])
      redirect_to new_gig_path, notice: "Congraulations! Your transaction has been successfully!"
    else
      flash[:alert] = "Something went wrong while processing your transaction. Please try again!"
      render :new
    end
  end

private
def generate_client_token
  Braintree::ClientToken.generate
end

def token_params
  params.require(:token).permit(:user_id)
end
def find_user
  @user = User.find(params[:user_id])
end
end

but I get an error 'Couldn't find User with 'id'='

The braintree clienttokens get generated in the tokens controller as the form is on the new token page. This works.

This is my last try at doing this but I have tried multiple ways of creating the tokens for the current_user but I cannot get it to work. The token model attributes are token_id and user_id.

Help would be appreciated, thanks.

Upvotes: 1

Views: 2320

Answers (2)

Andy Gauge
Andy Gauge

Reputation: 1428

Your before_action sets the @user using the parameters sent from the request. before_action :find_user means regardless of the action within the TransactionController, before running any code, run the code in find_user. In find_user, @user variable is set using request parameters. Request parameters are those sent within the form or the query string. A create method is called using a post action, which means the parameters should include all the properties within the form whose submit action was called. In your form view, I see two nested forms.

With nested resources, like the route file above reflects, Nested Resources on Rails Guides demonstrates the user_id is set by the path to the transaction submit. That means your url helper for the form action needs to be user_transactions_url(@user). Essentially the form needs to direct to /users/[:user_id]/transactions

It may be easier to use Rail's form_for helper found on the API. This is a very complicated solution that has many things fundamentally wrong with them. I've never seen anything like params[:user_id => current_user.id] I'm guessing you are trying to do hash assignment inside of a lookup Ruby doc.

Two pieces of advice:

  • Start with something simple
  • Conform to Rails conventions

Happy scripting

Upvotes: 1

Rob Hughes
Rob Hughes

Reputation: 906

Fixed:

before_action :find user

and

def find_user
  @user = User.find(params[:user_id])
end

wern't needed.

Removing them and adding

Token.create(user_id: current_user.id)

has fixed it. Thank you.

Upvotes: 1

Related Questions