3

今天早上我醒来时遇到了一个奇怪的问题,其中 mongoid 正在为模型中未定义的属性创建记录

为了克服这个问题,我决定实现 attr_accessible 也在 Mongoid规范中提到

“提供可访问的字段列表只是保护它们的反面。任何未定义为可访问的内容都会导致错误。” -- Mongoid 规范

认为一切都会好起来的

"任何未定义为可访问的内容都会导致错误

这是我的模型结构

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

这里是我从控制台创建的记录

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

知道为什么会这样吗?

谢谢

4

1 回答 1

2

您的问题是有效的——从以下测试和对 Mogoid 代码的粗略阅读来看,文档似乎不一致、不完全正确并且有些过时。

attr_protected 或 NOT attr_accessible 的字段忽略批量分配;他们不会在质量分配上引发错误。

在受保护的部分中,“引发错误”是不正确的,文档甚至与用户和人员不匹配。在 Accessible 部分中,“将导致错误”是不正确的,但“静默忽略受保护的”注释提供了一个线索,即没有引发错误并且忽略了批量分配。

这是来自 mongoid/spec/mongoid/attributes_spec.rb 的片段,它支持这一点。

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

您必须将字段 customer_id 添加到您的 PartPriceRecord 模型中。我对 User 和 PartPriceRecord 的测试如下。希望这会有所帮助。

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
于 2012-05-08T16:17:45.873 回答