Rails控制器接收所有参数,但无法正确创建数据库记录

问题描述

| 我要直截了当地说,根据我的日志文件,当我提交表单以创建新记录时,所有参数均正确发送,但是在创建表单时某些属性无法设置记录在数据库中。以下是相关的日志条目:
Started POST \"/computers\" for 192.168.8.70 at 2011-05-19 16:24:31 -0400
  Processing by ComputersController#create as HTML
  Parameters: {\"utf8\"=>\"✓\",\"authenticity_token\"=>\"agR6MrYbMTbXeR9+Oit0rUzrhcKuhg6p/jpGqQD9MhI=\",\"show_location_buttons\"=>\"1\",\"computer\"=>{\"vendor_id\"=>\"1\",\"new_vendor_name\"=>\"\",\"model\"=>\"Hello\",\"hostname\"=>\"Hello\",\"user_id\"=>\"\",\"computer_type\"=>\"Desktop\",\"serial_number\"=>\"\",\"unh_id\"=>\"\",\"doc_id\"=>\"\",\"federal\"=>\"0\",\"department_id\"=>\"\",\"new_department_name\"=>\"\",\"security_id\"=>\"\",\"purchase_price\"=>\"\",\"purchase_date\"=>\"05/11/2011\",\"warranty_expiration\"=>\"05/28/2011\",\"activity_id\"=>\"\",\"new_activity_code\"=>\"\",\"condition_id\"=>\"\",\"new_condition_name\"=>\"\",\"location_id\"=>\"\",\"operating_system\"=>\"Fedora Core\",\"comments\"=>\"\"},\"commit\"=>\"Create Computer\"}
  User Load (0.1ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 48 LIMIT 1
  sql (0.1ms)  BEGIN
  sql (0.4ms)  SHOW TABLES
  Computer Load (0.2ms)  SELECT `computers`.`id` FROM `computers` WHERE (`computers`.`hostname` = BINARY \'Hello\') LIMIT 1
  vendor Load (0.1ms)  SELECT `vendors`.* FROM `vendors` WHERE `vendors`.`id` = 1 LIMIT 1
  sql (0.7ms)  describe `computers`
  AREL (0.3ms)  INSERT INTO `computers` (`vendor_id`,`model`,`hostname`,`computer_type`,`serial_number`,`unh_id`,`doc_id`,`federal`,`department_id`,`security_id`,`purchase_price`,`purchase_date`,`warranty_expiration`,`activity_id`,`condition_id`,`location_id`,`operating_system`,`license_sticker_id`,`comments`,`created_at`,`updated_at`,`user_id`,`delta`) VALUES (1,\'Hello\',\'Desktop\',\'\',NULL,\'2011-11-05\',\'Fedora Core\',\'2011-05-19 20:24:31\',1)
如果仔细观察,则会在参数哈希中设置\'warranty_expiration \'的参数,但是如果您查看日志中的AREL行,则向数据库中的插入操作会删除保修_expiration字段的值并插入NULL。我对此完全傻眼了。有什么想法吗? 以下是我对计算机资源的模型和控制器代码: computer.rb
  class Computer < ActiveRecord::Base
    before_validation :format_fields

    validates :model,:presence => true
    validates :hostname,:presence => true,:uniqueness => true,:format => { :with => /^[a-zA-Z0-9]{3,25}$/ }
    validates :computer_type,:presence => true
    validates :operating_system,:presence => true

    validate :required_fields_specified

    belongs_to :vendor
    belongs_to :department
    belongs_to :security
    belongs_to :activity
    belongs_to :condition
    belongs_to :location
    belongs_to :license_sticker
    belongs_to :user

    has_many :hardware_addresses,:as => :addressable
    accepts_nested_attributes_for :hardware_addresses,:allow_destroy => true,:reject_if => lambda { |attr| attr[:mac_address].blank? }

    has_many :license_stickers,:dependent => :destroy
    accepts_nested_attributes_for :license_stickers,:reject_if => lambda { |attr| attr[:key].blank? or attr[:operating_system].blank? }

    has_many :pictures,:as => :imageable,:dependent => :destroy
    accepts_nested_attributes_for :pictures,:allow_destroy => true

    attr_accessor :new_vendor_name
    attr_accessor :new_activity_code
    attr_accessor :new_department_name
    attr_accessor :new_condition_name

    before_save :create_vendor_from_name
    before_save :create_activity_from_code
    before_save :create_department_from_name
    before_save :create_condition_from_name

    OPErating_SYstemS = [\"Microsoft Windows XP x86\",\"Microsoft Windows 7 x86\",\"Microsoft Windows Server 2003\",\"Microsoft Windows XP x64\",\"Microsoft Windows 7 x64\",\"Microsoft Windows Server 2008 x86\",\"Microsoft Windows Vista x86\",\"Microsoft Windows Vista x64\",\"Microsoft Windows Server 2008 x64\",\"Ubuntu 8.x\",\"Ubuntu 9.x\",\"Ubuntu 10.x\",\"Fedora Core\",\"CentOS 5.x x86\",\"CentOS 4 x86\",\"IRIX\",\"MacOS 10.5\",\"MacOS 10.6\",\"MacOS 10.7\",\"CentOS 4 x64\",\"CentOS 5 x64\",\"ESX 3\",\"ESX 4\",\"SUSE\"]

    COmpuTER_TYPES = [\"Desktop\",\"Laptop\",\"Server\"]

    def required_fields_specified
      errors.add_to_base \"Specify an existing vendor,or create one.\" if vendor.blank? and new_vendor_name.blank?
    end

    def create_vendor_from_name
      create_vendor(:name => new_vendor_name) unless new_vendor_name.blank?
    end

    def create_activity_from_code
      create_activity(:code => new_activity_code) unless new_activity_code.blank?
    end

    def create_department_from_name
      create_department(:name => new_department_name) unless new_department_name.blank?
    end

    def create_condition_from_name
      create_condition(:name => new_condition_name) unless new_condition_name.blank?
    end

    def format_fields
      serial_number.upcase!
      hostname.capitalize!
      self.model = self.model.titleize
      unh_id.upcase!
      doc_id.upcase!
    end

    define_index do
      indexes vendor(:name),:as => :vendor_name,:sortable => true
      indexes model,:sortable => true
      indexes hostname,:sortable => true
      indexes computer_type,:sortable => true
      indexes serial_number,:as => :serial,:sortable => true
      indexes operating_system,:as => :os,:sortable => true
      indexes activity(:code),:as => :activity_code
      indexes condition(:name),:as => :condition_name
      indexes department(:name),:as => :department_name
      indexes license_sticker(:key),:as => :license_key
      indexes license_sticker(:operating_system),:as => :licensed_os

      has warranty_expiration,:as => :warranty
      set_property :delta => true
    end

  end
computers_controller.rb
class ComputersController < ApplicationController
  filter_access_to :all

  # GET /computers
  # GET /computers.xml
  def index
    @computers = Computer.search params[:search],:order => sort_column(\"computer_type\"),:sort_mode => sort_direction,:per_page => 20,:page => params[:page],:star => true

    respond_to do |format|
      format.html # index.html.erb
      format.js
      format.xml  { render :xml => @computers }
    end
  end

  # GET /computers/1
  # GET /computers/1.xml
  def show
    @computer = Computer.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @computer }
    end
  end

  # GET /computers/new
  # GET /computers/new.xml
  def new
    @computer = Computer.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @computer }
    end
  end

  # GET /computers/1/edit
  def edit
    @computer = Computer.find(params[:id])
  end

  # POST /computers
  # POST /computers.xml
  def create
    @computer = Computer.new(params[:computer])

    respond_to do |format|
      if @computer.save
        format.html { redirect_to(@computer,:notice => \'Computer was successfully created.\') }
        format.xml  { render :xml => @computer,:status => :created,:location => @computer }
      else
        format.html { render :action => \"new\" }
        format.xml  { render :xml => @computer.errors,:status => :unprocessable_entity }
      end
    end
  end

  # PUT /computers/1
  # PUT /computers/1.xml
  def update
    @computer = Computer.find(params[:id])

    respond_to do |format|
      if @computer.update_attributes(params[:computer])
        format.html { redirect_to(@computer,:notice => \'Computer was successfully updated.\') }
        format.xml  { head :ok }
      else
        format.html { render :action => \"edit\" }
        format.xml  { render :xml => @computer.errors,:status => :unprocessable_entity }
      end
    end
  end

  # DELETE /computers/1
  # DELETE /computers/1.xml
  def destroy
    @computer = Computer.find(params[:id])
    @computer.destroy

    respond_to do |format|
      format.html { redirect_to(computers_url) }
      format.xml  { head :ok }
    end
  end

  private

  # def sort_column
  #   params[:sort] || \"computer_type\"
  # end

  # def sort_direction
  #   if params[:direction].nil?
  #     :asc
  #   else
  #     params[:direction].to_sym
  #   end
  # end
end
更新:在下面的rails控制台中执行请求的行的结果。   ruby-1.9.2-p180:002>   Computer.create! \“ vendor_id \” => \“ 1 \”,   \“ new_vendor_name \” => \“ \”,   \“ model \” => \“ Hello \”,\“主机名\” => \“ Heo \”,   \“ user_id \” => \“ \”,   \“ computer_type \” => \“桌面\”,   \“ serial_number \” => \“ \”,\“ unh_id \” => \“ \”,   \“ doc_id \” => \“ \”,\“ federal \” => \“ 0 \”,   \“ department_id \” => \“ \”,   \“ new_department_name \” => \“ \”,   \“ security_id \” => \“ \”,   \“购买价格\” => \“ \”,   \“购买日期\” => \“ 2011年5月11日”,   \“ warranty_expiration \” => \“ 2011/05/28”,   \“ activity_id \” => \“ \”,   \“ new_activity_code \” => \“ \”,   \“ condition_id \” => \“ \”,   \“ new_condition_name \” => \“ \”,   \“ location_id \” => \“ \”,   \“ operating_system \” => \“ Fedora Core \”,   \“评论\” => \“ \” Sphinx 0.9.9版本   (r2117)版权所有(c)2001-2009,   安德鲁·阿克西诺夫(Andrew Aksyonoff)      使用配置文件   \'/ opt / intranet3-dev / config / development.sphinx.conf \'...   索引索引\'computer_delta \'...   收集了2个文档,0.0 MB已排序0.0   Mhits,占完成总数的100.0%2个文档,62   字节总计0.016秒,3724字节/秒,   120.15文档/秒,共20次读取,0.000秒,0.0 kb /呼叫,平均,0.0毫秒/呼叫   平均10次写入,0.000秒,0.4   kb /通话平均值,0.0毫秒/通话平均值   旋转索引:成功发送   SIGHUP到searchd(pid = 25435)。 =>            computer_type:\“桌面\”,   serial_number:\“ \”,unh_id:\“ \”,doc_id:   \“ \”,联邦:false,department_id:   无,安全性ID:无,购买价格:   零,购买日期:\“ 2011-11-05 \”,   保修到期日:无,活动ID:   零,condition_id:零,location_id:   nil,操作系统:\“ Fedora Core \”,   license_sticker_id:无,注释:\“ \”,   created_at:\“ 2011-05-19 21:17:55 \”,   Updated_at:\“ 2011-05-19 21:17:55 \”,   user_id:无,增量:true> 谢谢您的帮助, 莱斯     

解决方法

在Rails控制台中执行以下代码
Computer.create! \"vendor_id\"=>\"1\",\"new_vendor_name\"=>\"\",\"model\"=>\"Hello\",\"hostname\"=>\"Hello\",\"user_id\"=>\"\",\"computer_type\"=>\"Desktop\",\"serial_number\"=>\"\",\"unh_id\"=>\"\",\"doc_id\"=>\"\",\"federal\"=>\"0\",\"department_id\"=>\"\",\"new_department_name\"=>\"\",\"security_id\"=>\"\",\"purchase_price\"=>\"\",\"purchase_date\"=>\"05/11/2011\",\"warranty_expiration\"=>\"05/28/2011\",\"activity_id\"=>\"\",\"new_activity_code\"=>\"\",\"condition_id\"=>\"\",\"new_condition_name\"=>\"\",\"location_id\"=>\"\",\"operating_system\"=>\"Fedora Core\",\"comments\"=>\"\"
并检查抛出哪种异常。     ,
Open rails console --sandbox
$ computer = Computer.new
$  computer.model = \'abc\'
$  computer.new_vendor_name = \'xyz\'
$ Keep adding required column values.
$ now try computer.save
# if it prompts true,then your data has been saved successfully if you get false then you have error in your code.

$ computer.errors.full_messages

#above command will list out,where your failed the validations(added in Model).