1

I have a coupon system, and I'm trying to get the coupon object with the method find_by:

Coupon.find_by_coupon(params[:coupon])

I'm getting this error:

ArgumentError Exception: Unknown key: coupon

I'm sure params[:coupon] is right:

(rdb:1) eval params[:coupon]
{"coupon"=>"100"}

I have the following model:

# Table name: coupons
#
#  id              :integer         not null, primary key
#  coupon          :string(255)
#  user_id         :integer

UPDATE:

It's working if I put Coupon.find_by_coupon(params[:coupon][:coupon]) instead of Coupon.find_by_coupon(params[:coupon]).

Here the code with the form in my view:

<%= semantic_form_for Coupon.new, url: payment_summary_table_offers_path(@booking_request) do |f| %>
    <%= f.input :coupon, :as => :string, :label => false, no_wrapper: true %>
    <%= f.action :submit, :as => :button, :label => t(:button_use_coupon), no_wrapper: true,
    button_html: { value: :reply, :disable_with => t(:text_please_wait) } %>
<% end %>
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
bl0b
  • 926
  • 3
  • 13
  • 30
  • This should work. Can you post the full stack trace of this error? – tadman Nov 22 '12 at 15:55
  • Oooh do you have a model `Coupon` having an attribute named `coupon` also? Try to rename your column `coupon_code` – MrYoshiji Nov 22 '12 at 15:57
  • 1
    Do you try to set the value(100) direct. to see if the error is somewhere else? – Festus Tamakloe Nov 22 '12 at 16:00
  • 2
    Maybe your Hash is containing your coupon object, and to access to the coupon attribute you should do `params[:coupon][:coupon]`. Have you tried that ? – MrYoshiji Nov 22 '12 at 16:05
  • @MrYoshiji it's working and Festado's solution is also working ! So, any idea why ? This is crazy (I updated my original post) – bl0b Nov 22 '12 at 16:10

1 Answers1

2

If you are using Rails 3, I advise you to find object using this method:

# equivalent of find_all
Coupon.where(:coupon => params[:coupon]) # => Returns an array of Coupons
# equivalent of find :first
Coupon.where(:coupon => params[:coupon]).first # => Returns a Coupon or nil

Try to do a params.inspect to see exactly how is made your Hash. I think it is built like this:

{ :coupon => { :coupon => '100' } }

If it is, you should use params[:coupon][:coupon] to get the String '100'

Following your update:

semantic_form_for is creating the form for you, as you give him a Coupon.new it will build the params this way:

params = {
  :coupon => { :attribute_1 => 'value_1', :attribute_2 => 'value_2' }
}

If you prefer to use the find_by method:

Coupon.find_by_coupon(params[:coupon][:coupon]) # => Returns a Coupon or raise a RecordNotFound error

Or with the where method:

Coupon.where(:coupon => params[:coupon][:coupon]).first # => Returns a Coupon or nil
MrYoshiji
  • 54,334
  • 13
  • 124
  • 117
  • Why is this way to do it better than find_by ? – bl0b Nov 22 '12 at 16:16
  • Thanks ! Since the form will contain only one coupon at the time, what should I specify to semantic_form_for to send only one coupon instead of an array of coupons. – bl0b Nov 22 '12 at 16:49
  • It is not sending an array of Coupons to semantic_form_for. It is just passing only one Coupon object. Then it "scopes" the attributes in the params[:coupon], representing a Hash of attributes for the Coupon.new object. – MrYoshiji Nov 22 '12 at 16:56