Rails错误与验证和多个模型,无法将HashWithIndifferentAccess转换为String

时间:2009-10-26 16:57:04

标签: ruby-on-rails

我从1.2版本开始就没有使用过rails,但有些东西已经改变了。我有一个问题,我试图保存一个空模型,以使用:validates_presence_of获取属性验证错误,而我得到错误'无法将HashWithIndifferentAccess转换为字符串'。我将尝试简化我的代码,尽可能简洁地解决问题...

我的模特:

class Project < ActiveRecord::Base

    validates_presence_of :title, :description
    validates_uniqueness_of :title

    has_one :address

    accepts_nested_attributes_for :address, :allow_destroy => true
end

儿童模特:

class Address < ActiveRecord::Base
    validates_presence_of :title, :street
    belongs_to :project
end

控制器:

class ProjectsController < ApplicationController
    def create
        @project = Project.new(params[:project])
        if @project.save
            flash[:notice] = @project.title + ' successfully created'
            redirect_to projects_path
        else
            render :action => 'new'
        end
    end
end

视图:

<%= error_messages_for 'project' %>
<% form_for @project do |f| %>
<table width="100%" cellpadding="3" cellspacing="0">
    <tr>
        <td class="adminlabel">
            <label for="Title">Title</label>
        </td>
        <td class="adminbody">
            <%= f.text_field :title %>
        </td>
    </tr>   
    .....
    <% f.fields_for :address do |address| %>
    ....

只要我填写所有必填字段,此代码就添加和更新就好了,如果我留下任何空白我得到上面提到的错误,而不是提醒用户最优雅的方式有问题;)

请求参数:
{ “提交”=&gt; “中保存”,
 “项目”=&GT; { “标题”=&gt; “中”,
 “注释”=&gt; “中”,
 “描述”=&gt; “中”,
 “address_attributes”=&GT; { “城市”=&gt; “中”,
 “拉链”=&gt; “中”,
 “标题”=&gt; “中”,
 “国家”=&gt; “中”,
 “套件”=&gt; “中”,
 “街道”=&gt; “中”,
 “状态”=&gt; “中”}},
 “authenticity_token”=&gt;“iNPQZrf / oBv22vaI0toTGhknwx0aAU3BSvnIh6qgYQ8 =”}

我一直在寻找好几天,我的智慧结束了,如果有人能为我揭开这一点,我会非常感激。

提前致谢!

布兰登

PS - 请求的堆栈跟踪:

.../app/controllers/projects_controller.rb:27:in `+'  
.../app/controllers/projects_controller.rb:27:in `create'  
../actionpack-2.3.4/lib/action_controller/base.rb:1331:in `send'  
../actionpack-2.3.4/lib/action_controller/base.rb:1331:in `perform_action_without_filters'  
../actionpack-2.3.4/lib/action_controller/filters.rb:617:in `call_filters'  
../actionpack-2.3.4/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'  
../actionpack-2.3.4/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'  
../activesupport-2.3.4/lib/active_support/core_ext/benchmark.rb:17:in `ms'  
../activesupport-2.3.4/lib/active_support/core_ext/benchmark.rb:10:in `realtime'  
../activesupport-2.3.4/lib/active_support/core_ext/benchmark.rb:17:in `ms'  
../actionpack-2.3.4/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'  
../actionpack-2.3.4/lib/action_controller/rescue.rb:160:in `perform_action_without_flash'  
../actionpack-2.3.4/lib/action_controller/flash.rb:146:in `perform_action'  
../actionpack-2.3.4/lib/action_controller/base.rb:532:in `send'  
../actionpack-2.3.4/lib/action_controller/base.rb:532:in `process_without_filters'  
../actionpack-2.3.4/lib/action_controller/filters.rb:606:in `process'  
../actionpack-2.3.4/lib/action_controller/base.rb:391:in `process'  
../actionpack-2.3.4/lib/action_controller/base.rb:386:in `call'  
../actionpack-2.3.4/lib/action_controller/routing/route_set.rb:437:in `call'  
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:87:in `dispatch'  
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:121:in `_call'  
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:130:in `build_middleware_stack'   
../activerecord-2.3.4/lib/active_record/query_cache.rb:29:in `call'  
../activerecord-2.3.4/lib/active_record/query_cache.rb:29:in `call'  
../activerecord-2.3.4/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'  
..activerecord-2.3.4/lib/active_record/query_cache.rb:9:in `cache'   
../activerecord-2.3.4/lib/active_record/query_cache.rb:28:in `call'  
../activerecord-2.3.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'  
../rack-1.0.1/lib/rack/head.rb:9:in `call'  
../rack-1.0.1/lib/rack/methodoverride.rb:24:in `call'  
../actionpack-2.3.4/lib/action_controller/params_parser.rb:15:in `call'  
../actionpack-2.3.4/lib/action_controller/session/cookie_store.rb:93:in `call'  
../actionpack-2.3.4/lib/action_controller/failsafe.rb:26:in `call'  
../rack-1.0.1/lib/rack/lock.rb:11:in `call'  
../rack-1.0.1/lib/rack/lock.rb:11:in `synchronize'  
../rack-1.0.1/lib/rack/lock.rb:11:in `call'  
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:114:in `call'  
../actionpack-2.3.4/lib/action_controller/reloader.rb:34:in `run'  
../actionpack-2.3.4/lib/action_controller/dispatcher.rb:108:in `call'  
../rails-2.3.4/lib/rails/rack/static.rb:31:in `call'  
../rack-1.0.1/lib/rack/urlmap.rb:46:in `call'  
../rack-1.0.1/lib/rack/urlmap.rb:40:in `each'  
../rack-1.0.1/lib/rack/urlmap.rb:40:in `call'  
../rails-2.3.4/lib/rails/rack/log_tailer.rb:17:in `call'  
../rack-1.0.1/lib/rack/content_length.rb:13:in `call'  
../rack-1.0.1/lib/rack/chunked.rb:15:in `call'  
../rack-1.0.1/lib/rack/handler/mongrel.rb:64:in `process'
..... etc.

有点冗长,对不起;)

2 个答案:

答案 0 :(得分:2)

尝试添加

@project.address.build

到您的控制器。您需要实例化地址对象。

答案 1 :(得分:2)

痕迹不是谎言。您遇到了第27行的问题。您发布的代码没有37行,但基于跟踪我愿意打赌它就是这一行。因为没有其他人有'+'。如果有一个隐含的+它的调用者将被列在跟踪中。

 flash[:notice] = @project.title + ' successfully created'

根据您的验证,它达到了这一点,这很奇怪。 validates_presence_of应该在nil,false或“”属性上添加错误。在控制台中运行时,验证是否按预期失败?

这是您的代码的友好控制台版本,可用于追踪您的问题。您应该可以将其粘贴到控制台中,以帮助追踪您的问题。

params = {
  "project"=> {
    "title"=>"", "notes"=>"","description"=>"", 
    "address_attributes"=>{
      "city"=>"", "zip"=>"","title"=>"","country"=>"",
      "suite"=>"","street"=>"","state"=>""
    }
   }
flash = {}

@project = Project.new(params[:project])
if @project.save
  flash[:notice] = @project.title + ' successfully created'
  puts "Saved. Flash: #{flash[:notice]}"
else
  puts "validations failed:" 
  puts @project.errors.full_messages.map{|m| "\t#{m}"}.join("\n")
end