Today morning I wake with this weird issue where mongoid was creating a record for the attributes which isn't being defined in the model

To overcome this i decide to implement attr_accessible also mention in Mongoid specification

"Providing a list of fields as accessible is simply the inverse of protecting them. Anything not defined as accessible will cause the error." -- Mongoid Specification

Think all would work fine I create a dummy record and too my surprise I got inserted as oppose to the statement above that

"Anything not defined as accessible will cause the error

Here my model structure

class PartPriceRecord 
  include Mongoid::Document
    field :supplier_id,type: Integer
    field :part_number,type: String
    field :part_description, type: String
    field :core_indicator,type: String
    field :us_part_price,type: Float
    field :us_core_price,type: Float
    field :us_fleet_price,type: Float
    field :us_distributor_price,type: Float
    field :ca_part_price,type: Float
    field :ca_distributor_price,type: Float
    field :ca_core_price,type: Float
    field :ca_fleet_price,type: Float 
    field :basic_file_id,type: Integer
    index :part_number, unique: true

  validates_presence_of :supplier_id
  validates_presence_of :part_number
  #validates_uniqueness_of :part_number
  validates :part_number ,:format => { :with => /^[a-z0-9A-Z\s*-]+[-a-z0-9\s-]*[a-z0-9\s*-]+$/i ,:message => "Only AlphaNumeric Allowed" }
  validates :supplier_id, :format => { :with => /^[a-z0-9]+[-a-z0-9]*[a-z0-9]+$/i , :message => "Only Alphanumeric Allowed" } 
  #validates :part_description,:presence => true

  validates :part_description,:format => { :with => /^[a-z0-9]+[-a-z0-9]*[a-z0-9]+$/i ,:message => "Only Alphanumberic Allowed"} ,:allow_nil => true
  validates :core_indicator ,:inclusion => { :in => %w(Y N),
    :message => "%{value} is not a valid Coreindicator must be Y | N" 
   } ,:allow_nil => true,:allow_blank => true


 validates :us_part_price,:us_core_price,:us_fleet_price,:us_distributor_price,:ca_part_price,:ca_core_price,:ca_fleet_price,:ca_distributor_price ,:format => { :with => /^([0-9]+(\.([0-9]{2}|[0-9]{1}))?)$/ ,:message => "should look like money" } ,:allow_nil => true,:allow_blank => true

  @@required_attributes =[:supplier_id,:part_number,:part_description,:core_indicator,:us_part_price,:us_core_price,:us_fleet_price,:us_distributor_price,:ca_part_price,:ca_core_price,:ca_fleet_price,:ca_distributor_price]
  @@not_required_attributes = ["_id","basic_file_id"]  
  cattr_reader :required_attributes,:not_required_attributes
  attr_accessible :supplier_id,:part_number,:part_description, :core_indicator,:us_part_price,:us_core_price,:us_fleet_price,:us_distributor_price,:ca_part_price,:ca_distributor_price,:ca_core_price,:ca_fleet_price,:basic_file_id
end

and Here the record I creating from my console

ruby-1.9.2-head :003 > PartPriceRecord.count()
 => 260317 ## initial count before creating a new record
ruby-1.9.2-head :004 > p1 = PartPriceRecord.new(:customer_id => "One",:part_number => "ASA",:supplier_id => "Supp")
 => #<PartPriceRecord _id: 4fa77921d2d8d60e39000002, _type: nil, supplier_id: "Supp", part_number: "ASA", part_description: nil, core_indicator: nil, us_part_price: nil, us_core_price: nil, us_fleet_price: nil, us_distributor_price: nil, ca_part_price: nil, ca_distributor_price: nil, ca_core_price: nil, ca_fleet_price: nil, basic_file_id: nil> 
ruby-1.9.2-head :005 > p1.save
 => true  ## Record got created
ruby-1.9.2-head :006 > PartPriceRecord.count()
 => 260318  ## Count indicating record was created

Any idea why is this so ?

Thanks

有帮助吗?

解决方案

Your question is valid -- it appears that the documentation is inconsistent, not fully correct, and somewhat outdated, from the following tests and cursory reading of Mogoid code.

Fields that are attr_protected or NOT attr_accessible ignore mass assignment; they do NOT raise an error on mass assignment.

In the section on Protected, "raising an error" is incorrect, and the documentation even mismatches User and Person. In the section on Accessible, "will cause the error" is incorrect, but the comment "silently ignore protected ones" gives a clue that no error is raised and that the mass assignment is ignored.

Here's a fragment from mongoid/spec/mongoid/attributes_spec.rb that supports this.

describe ".attr_accessible" do

  context "when the field is not _id" do

    let(:account) do
      Account.new(number: 999999)
    end

    it "prevents setting via mass assignment" do
      account.number.should be_nil
    end
  end
...
end

You must add the field customer_id to your PartPriceRecord model. My tests for User and PartPriceRecord follow. Hope that this helps.

require 'test_helper'

class PartPriceRecordTest < ActiveSupport::TestCase
  def setup
    User.delete_all
    PartPriceRecord.delete_all
  end

  test "User" do
    assert_equal(0, User.count())
    # Set attributes on a user properly.
    user = User.new(first_name: "Corbin")
    assert_equal("Corbin", user.first_name)
    user.attributes = { first_name: "Corbin" }
    assert_equal("Corbin", user.first_name)
    user.write_attributes(first_name: "Corbin")
    assert_equal("Corbin", user.first_name)

    # Attempt to set attributes a user, raising an error. # <-- This documentation is incorrect, no error is raised
    #user = User.new(first_name: "Corbin", password: "password")
    user.attributes = { first_name: "Corbin", password: "password" } # inaccessible field is forced to nil
    assert_equal("Corbin", user.first_name)
    assert_equal(nil, user.password)
    user.write_attributes(first_name: "Corbin", password: "password") # inaccessible field is forced to nil
    assert_equal("Corbin", user.first_name)
    assert_equal(nil, user.password)
  end

  test "PartPriceRecord" do
    assert_equal(0, PartPriceRecord.count())
    p1 = PartPriceRecord.new(:customer_id => "One",:part_number => "ASA",:supplier_id => "Supp")
    assert_equal(nil, p1.customer_id)
    p1.save
    assert_equal(1, PartPriceRecord.count())
    assert_equal(nil, PartPriceRecord.find(p1.id).customer_id)
  end
end
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top