Why some model attributes not saved in the db?

2019-08-18 05:16发布

问题:

I have a Quote model in my rails app which has various attr types, some of which are being sent to / saved by the db, some are not and I cannot understand why. Please can you help me understand, thanks.

quotes_controller.rb

class QuotesController < ApplicationController

  def create
    @quote = Quote.new(quote_params)
    if @quote.save
        redirect_to root_url, notice: 'Quote request created'
    else
      render :new
    end
  end

private

  def quote_params
    params.require(:quote).permit(:gla, :prev_cover, :co_name, :postcode, :industry, :lives_overseas, 
                                  :scheme_start_date, :payment_frequency, :commision_level)
  end
end

quote.rb model

class Quote < ApplicationRecord
        validates :gla, presence: { message: "Must be selected" }

        enum industry:          [ :financial_services, :architect, :business_consultancy ]
        enum payment_frequency: [ :annually, :monthly ]
end

schema.rb

create_table "quotes", force: :cascade do |t|
    t.boolean  "prev_cover"
    t.string   "co_name"
    t.integer  "co_number"
    t.string   "postcode"
    t.string   "industry"
    t.boolean  "lives_overseas"
    t.date     "scheme_start_date"
    t.string   "payment_frequency"
    t.integer  "commission_level"
    t.datetime "created_at",        null: false
    t.datetime "updated_at",        null: false
    t.boolean  "gla"
  end

rails console:

Pry> Quote.last.attributes
  Quote Load (0.4ms)  SELECT  "quotes".* FROM "quotes" ORDER BY "quotes"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> {"id"=>6,
 "prev_cover"=>true,
 "co_name"=>"test1",
 "co_number"=>nil,
 "postcode"=>"al1 1aa",
 "industry"=>nil,
 "lives_overseas"=>true,
 "scheme_start_date"=>Wed, 31 May 2017,
 "payment_frequency"=>nil,
 "commission_level"=>nil,
 "created_at"=>Wed, 31 May 2017 19:23:07 UTC +00:00,
 "updated_at"=>Wed, 31 May 2017 19:23:07 UTC +00:00,
 "gla"=>true}

Stack Trace:

Started POST "/quotes" for 127.0.0.1 at 2017-05-31 21:04:37 +0100
Processing by QuotesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"ILAo0Bs9Wq9lrVPlM2e6+a1kioV9zbni9Uxd5Yt/QSLNY3aVWyJ4TsEUmXN62RWgbueHksr/yN6avwEm8v7bEQ==", "quote"=>{"gla"=>"1", "prev_cover"=>"true", "co_name"=>"testing1", "co_number"=>"123456", "postcode"=>"al1 1aa", "industry"=>"", "lives_overseas"=>"true", "scheme_start_date(1i)"=>"2017", "scheme_start_date(2i)"=>"5", "scheme_start_date(3i)"=>"31", "payment_frequency"=>"", "commission_level"=>"10"}, "commit"=>"Get quote"}
Unpermitted parameters: co_number, commission_level
   (0.1ms)  BEGIN
  SQL (0.2ms)  INSERT INTO "quotes" ("prev_cover", "co_name", "postcode", "lives_overseas", "scheme_start_date", "created_at", "updated_at", "gla") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["prev_cover", "t"], ["co_name", "testing1"], ["postcode", "al1 1aa"], ["lives_overseas", "t"], ["scheme_start_date", "2017-05-31"], ["created_at", "2017-05-31 20:04:37.489368"], ["updated_at", "2017-05-31 20:04:37.489368"], ["gla", "t"]]
   (0.3ms)  COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 3ms (ActiveRecord: 0.6ms)


Started GET "/" for 127.0.0.1 at 2017-05-31 21:04:37 +0100
Processing by QuotesController#new as HTML
  Rendering quotes/new.html.erb within layouts/application
  Rendered quotes/new.html.erb within layouts/application (9.3ms)
Completed 200 OK in 34ms (Views: 32.7ms | ActiveRecord: 0.0ms)

From Rails console.

[1] pry(main)> Quote.last
  Quote Load (0.2ms)  SELECT  "quotes".* FROM "quotes" ORDER BY "quotes"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> #<Quote:0x007f951b14e918
 id: 7,
 prev_cover: true,
 co_name: "testing1",
 co_number: nil,
 postcode: "al1 1aa",
 industry: nil,
 lives_overseas: true,
 scheme_start_date: Wed, 31 May 2017,
 payment_frequency: nil,
 commission_level: nil,
 created_at: Wed, 31 May 2017 20:04:37 UTC +00:00,
 updated_at: Wed, 31 May 2017 20:04:37 UTC +00:00,
 gla: true>

Ok stack trace and @toddmetheny help me sort out the missing or typo'd permitted attrs. Now just the enums Quote.industries and Quote.payment_frequencies whose values aren't getting saved.

Ok, so code changed to;

And this sends the attrs from the form, but they still don't get created in the db, stack trace:

Started POST "/quotes" for 127.0.0.1 at 2017-05-31 21:39:58 +0100
Processing by QuotesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"rkgX7CwrEHS/KnqG1C77mYkCiCEOWGshTxMCsbtGPdjGiDP20J4ccrAgplAGuKrdJyhECRWrsmXI0Ee9GNa6Zw==", "quote"=>{"gla"=>"1", "prev_cover"=>"true", "co_name"=>"halejulia", "co_number"=>"134532", "postcode"=>"al1 1aa", "industry"=>"financial_services", "lives_overseas"=>"true", "scheme_start_date(1i)"=>"2017", "scheme_start_date(2i)"=>"5", "scheme_start_date(3i)"=>"31", "payment_frequency"=>"monthly", "commission_level"=>"10"}, "commit"=>"Get quote"}
   (0.1ms)  BEGIN
  SQL (0.3ms)  INSERT INTO "quotes" ("prev_cover", "co_name", "co_number", "postcode", "industry", "lives_overseas", "scheme_start_date", "payment_frequency", "commission_level", "created_at", "updated_at", "gla") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id"  [["prev_cover", "t"], ["co_name", "halejulia"], ["co_number", 134532], ["postcode", "al1 1aa"], ["industry", 0], ["lives_overseas", "t"], ["scheme_start_date", "2017-05-31"], ["payment_frequency", 1], ["commission_level", 10], ["created_at", "2017-05-31 20:39:58.957674"], ["updated_at", "2017-05-31 20:39:58.957674"], ["gla", "t"]]
   (0.3ms)  COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 3ms (ActiveRecord: 0.7ms)

rails console :

Quote.last.payment_frequency
  Quote Load (0.4ms)  SELECT  "quotes".* FROM "quotes" ORDER BY "quotes"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> nil

So still the params aren't being persisted in the db, they're permitted params! any ideas?

Strange, a psql select * from .. query shows that the values have been saved, yet Rails console; Quote.last.payment_frequency returns nil???

Aha, i see that for a enum the column type should be integer, yet it is string in my model, could this be the issue perhaps?

Data type of enum'd attrs changed to integer and all behaves as expected.

回答1:

Post the stack trace. co_number isn't whitelisted in the permitted params. So that's at least part of the issue with that particular field. The others are...but post what you're actually seeing in the logs so we can see what's being passed through the form. There will also be messages in the stack trace that give you clues as to why those values aren't saving.

Update: the stack trace lists 2 unpermitted parameters: co_number and commission_level (you have a typo permitting commission level and co_number isn't there)

A couple things have blank values, too...like payment_frequency and industry...I'd dig into why those things are blank if they shouldn't be. Does the form have values for those things? They aren't being passed. That seems to account for the rest of your nil values.