开发者

Rails error with validation and multiple models, can't convert HashWithIndifferentAccess into String

I haven't used rails since version 1.2 or so and a few things have changed. I have an issue where I am try开发者_开发技巧ing to save an empty model to get validation errors on attributes using :validates_presence_of and instead I am getting the error 'can't convert HashWithIndifferentAccess into String'. I will attempt to simplify my code to get the point across as tersely as possible...

my model:

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

Child model:

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

controller:

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

view:

<%= 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| %>
    ....

This code adds and updates just fine as long as I fill in all the required fields, if I leave any blank I get the error mentioned above, not the most graceful way of alerting users there is an issue ;)

Request params:

{"commit"=>"Save",

"project"=>{"title"=>"",

"notes"=>"",

"description"=>"",

"address_attributes"=>{"city"=>"",

"zip"=>"",

"title"=>"",

"country"=>"",

"suite"=>"",

"street"=>"",

"state"=>""}},

"authenticity_token"=>"iNPQZrf/oBv22vaI0toTGhknwx0aAU3BSvnIh6qgYQ8="}

I have been searching for days and am at my wits end, if anyone can shed a little light on this for me I would greatly appreciate it.

Thanks in advance!

Brendan

PS - the stack trace as requested:

.../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.

A bit lengthy, sorry ;)


Try adding

@project.address.build

to your controller. You need to instantiate the address object.


The trace doesn't lie. You're having issues with a line 27. The code you posted doesn't have 37 lines, but based on the trace I'm willing to bet it's this line. Because none others have have a '+'. If there was an implicit + its caller would've been listed in the trace.

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

It's odd that it's reaching that point based on your validations. validates_presence_of should add errors on attributes that are either nil, false or "". Does the validation fail as expected when run in the console?

Here's a console friendly version of your code that could be used to track down your issue. You should be able to just paste it into the console to help track down your issue.

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜