Aradeea
Aradeea

Reputation: 3

How to use a button to post in rails?

So I'm trying to create a new "transaction" each time I click the button "Purchase", but doesn't seem to work. I get the error "undefined method `[]' for nil:NilClass".

<% @comics.each do |comic|%>
  <ul>
  <li><%= comic.title %> </li>
  <li><%= comic.author %> </li>
  <li><%= comic.year %> </li>
  <li><%= comic.publisher %> </li>
  <% if user_signed_in? %>
  <%= button_to 'Purchase', {:controller => "transactions", :action => "create", :seller_id => comic.user_id, :buyer_id=> current_user.id, :comic_id => comic.id} , {:method=>:post}  %>
  <% end %>
</ul>

This is what you can find in the transactions controller:

  def create
    @my_transaction = Transaction.new(
        buyer_id: params[:transaction][:buyer_id],
        seller_id: params[:transaction][:seller_id],
        comic_id: params[:transaction][:comic_id]
    )
    @my_transaction.save
        redirect_to "/transactions/"
  end

Do you have any idea why this might be happening?

Thanks!

Upvotes: 0

Views: 1430

Answers (2)

Peter Toth
Peter Toth

Reputation: 1004

The params[:transaction] is nil, you can see the sent parameters in the log (tail -f log/development.log if the server doesn't log). In your case you access the required data like params[:comic_id]

A few tips:

Never trust the input coming from the client: :buyer_id=> current_user.id here an attacker could send any ID since the button_to helper will create a html form which is easily accessible using the devtool. Instead check it on the server side. Same goes for the seller_id, you can just fetch the related comic comic = Comic.find params[:comic_id].

You might want to consider an another API approach like POST /comics/1/buy this is a bit more restfull, and you could use the built in path helpers for that url like buy_comic_path(comic)

Upvotes: 1

margo
margo

Reputation: 2927

There are a couple of ways you can debug this:

  1. Look in the console logs to see what is being posted in the params hash.
  2. add a puts statement at the top of the create statement to view what is in the params variable e.g.

controller

def create
  puts params.inspect
end

I suspect you'll find that the params hash does not have a transaction key and the create method should be

def create
  @my_transaction = Transaction.new(
    buyer_id: params[:buyer_id],
    seller_id: params[:seller_id],
    comic_id: params[:comic_id]
)
end

Upvotes: 1

Related Questions