我从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.
有点冗长,对不起;)
答案 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