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

发布于 2024-11-09 05:47:36 字数 9919 浏览 0 评论 0原文

我要开门见山了,根据我的日志文件,当我提交表单创建新记录时,所有参数都发送正确,但是创建记录时有些属性设置失败在数据库中。以下是相关日志条目:

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', 'Hello', 'Desktop', '', '', '', 0, NULL, NULL, NULL, '2011-11-05', NULL, NULL, NULL, NULL, 'Fedora Core', NULL, '', '2011-05-19 20:24:31', '2011-05-19 20:24:31', NULL, 1)

如果您仔细观察,会发现“warranty_expiration”参数是在参数哈希中设置的,但是如果您查看日志中的 AREL 行,则会发现数据库中的插入操作会删除 Warranty_expiration 字段的值,并且插入 NULL。我对此完全傻眼了。有什么想法吗?

以下是我的计算机资源的模型和控制器代码:

computer.rbcomputers_controller.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, :allow_destroy => true, :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

更新:在下面的 Rails 控制台中执行请求

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

的行的结果。

ruby-1.9.2-p180:002>> 计算机.创建! “vendor_id”=>“1”, "new_vendor_name"=>"", “型号”=>“你好”,“主机名”=>“Heo”, "user_id"=>"", "computer_type"=>"桌面", “serial_number”=>“”,“unh_id”=>“”, “doc_id”=>“”,“联邦”=>“0”, "department_id"=>"", "new_department_name"=>"", “security_id”=>“”, “购买价格”=>“”, “购买日期”=>“2011 年 5 月 11 日”, "warranty_expiration"=>"05/28/2011", “activity_id”=>“”, “new_activity_code”=>“”, "condition_id"=>"", "new_condition_name"=>"", "location_id"=>"", "operating_system"=>"Fedora Core", “评论”=>“”Sphinx 0.9.9-release (r2117) 版权所有 (c) 2001-2009, 安德鲁·阿克肖诺夫

使用配置文件 '/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 毫秒/呼叫平均值 旋转索引:已成功发送 对 searchd 发出 SIGHUP (pid=25435)。 =>

计算机类型:“桌面”, 序列号:“”,unh_id:“”,doc_id: “”,联邦:假,department_id: 无,安全 ID:无,购买价格: 无,购买日期:“2011-11-05”, 保修期:无,活动 ID: 无,condition_id:无,location_id: nil,操作系统:“Fedora Core”, License_sticker_id:无,评论:“”, 创建时间:“2011-05-19 21:17:55”, 更新时间:“2011-05-19 21:17:55”, user_id: nil, delta: true>

感谢您的帮助,

莱斯

I'm going to get straight to the point, which is that according to my log file, when I submit a form to create a new record, all of the parameters are sent correctly, but some attributes fail to be set when creating the record in the database. Following is the pertinent log entry:

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', 'Hello', 'Desktop', '', '', '', 0, NULL, NULL, NULL, '2011-11-05', NULL, NULL, NULL, NULL, 'Fedora Core', NULL, '', '2011-05-19 20:24:31', '2011-05-19 20:24:31', NULL, 1)

If you look closely, the parameter for 'warranty_expiration' was set in the parameters hash, but if you look at the AREL line in the log, the insert into the database drops the value of the warranty_expiration field and inserts NULL. I'm completely dumbfounded by this. Any thoughts?

Following is my model and controller code for the Computer resource:

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, :allow_destroy => true, :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

UPDATE: Result from executing requested line in rails console below.

ruby-1.9.2-p180 :002 >
Computer.create! "vendor_id"=>"1",
"new_vendor_name"=>"",
"model"=>"Hello", "hostname"=>"Heo",
"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"=>"" Sphinx 0.9.9-release
(r2117) Copyright (c) 2001-2009,
Andrew Aksyonoff

using config file
'/opt/intranet3-dev/config/development.sphinx.conf'...
indexing index 'computer_delta'...
collected 2 docs, 0.0 MB sorted 0.0
Mhits, 100.0% done total 2 docs, 62
bytes total 0.016 sec, 3724 bytes/sec,
120.15 docs/sec total 20 reads, 0.000 sec, 0.0 kb/call avg, 0.0 msec/call
avg total 10 writes, 0.000 sec, 0.4
kb/call avg, 0.0 msec/call avg
rotating indices: succesfully sent
SIGHUP to searchd (pid=25435). =>

computer_type: "Desktop",
serial_number: "", unh_id: "", doc_id:
"", federal: false, department_id:
nil, security_id: nil, purchase_price:
nil, purchase_date: "2011-11-05",
warranty_expiration: nil, activity_id:
nil, condition_id: nil, location_id:
nil, operating_system: "Fedora Core",
license_sticker_id: nil, comments: "",
created_at: "2011-05-19 21:17:55",
updated_at: "2011-05-19 21:17:55",
user_id: nil, delta: true>

Thanks for the help,

Les

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清眉祭 2024-11-16 05:47:36

在 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"=>""

并检查抛出了哪种异常。

Execute in rails console this code

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"=>""

and check what kind of exception is thrown.

偏闹i 2024-11-16 05:47:36
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).
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).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文