Rails嵌套模型类型不匹配

时间:2012-06-04 00:23:32

标签: ruby-on-rails-3 heroku nested-attributes

我的应用程序在我的开发机器上运行没有任何问题。当我将它推送到Heroku时,我收到以下错误,导致应用程序崩溃:

ActiveRecord::AssociationTypeMismatch (Profile(#47183120) expected, got ActiveSupport::HashWithIndifferentAccess(#35109340))

从日志中可以看出:

153 <13>1 2012-06-04T00:07:57+00:00 app web.1 - - Started POST "/users" for 2.124.94.147/027c5e93.bb.sky.com at 2012-06-04 00:07:57 +0000
138 <13>1 2012-06-04T00:07:57+00:00 app web.1 - - Processing by RegistrationsController#create as HTML
517 <13>1 2012-06-04T00:07:57+00:00 app web.1 - -   Parameters: {"utf8"=>"✓", "authenticity_token"=>"ztrHyRb/VzLSNRKZI1ifP6NZfdXFacDGi6edxM7RCRM=", "user"=>{"email"=>"user@email.com", "username"=>"user", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "profile"=>{"full_name"=>"Some Name", "birth_date(3i)"=>"21", "birth_date(2i)"=>"10", "birth_date(1i)"=>"1985", "gender"=>"0", "postcode"=>"XXXX XXX", "description"=>"Site designer."}}, "commit"=>"Sign up"}
129 <13>1 2012-06-04T00:07:57+00:00 app web.1 - - Completed 500 Internal Server Error in 84ms
86 <13>1 2012-06-04T00:07:57+00:00 app web.1 - -
211 <13>1 2012-06-04T00:07:57+00:00 app web.1 - - ActiveRecord::AssociationTypeMismatch (Profile(#47001900) expected, got ActiveSupport::HashWithIndifferentAccess(#29446440)):

用户模型(来自Devise):

class User < ActiveRecord::Base
    # Include default devise modules. Others available are:
    # :token_authenticatable, :confirmable,
    # :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :trackable, :validatable

    # FriendlyID for slugs
    extend FriendlyId
    friendly_id :username, use: :slugged

    # Setup accessible (or protected) attributes for your model
    attr_accessible :email, :password, :password_confirmation, :profile_attributes, :remember_me, :username
    # attr_accessible :title, :body

    # Set relationships
    has_one :profile, dependent: :destroy
    accepts_nested_attributes_for :profile

    # Validation
    VALID_USERNAME_REGEX = /^[a-z0-9_]+$/i
    validates :username, presence: true, uniqueness: true, length: { minimum: 5, maximum: 15 }, format: { with: VALID_USERNAME_REGEX }

end

个人资料模型:

class Profile < ActiveRecord::Base
    attr_accessible :birth_date, :description, :full_name, :gender, :latitude, :longitude, :postcode

    belongs_to :user

    geocoded_by :geocode_string

    INVALID_NAME_REGEX = /^[^0-9`!@#\$%\^&*+_=]+$/
    VALID_POSTCODE_REGEX = /^\s*((GIR\s*0AA)|((([A-PR-UWYZ][0-9]{1,2})|(([A-PR-UWYZ][A-HK-Y][0-9]{1,2})|(([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))))\s*[0-9][ABD-HJLNP-UW-Z]{2}))\s*$/i
    validates :full_name, format: { with: INVALID_NAME_REGEX }, presence: true
    validates :birth_date, timeliness: { before: :today, type: :date }, presence: true
    validates :gender, presence: true
    validates :postcode, format: { with: VALID_POSTCODE_REGEX }, allow_blank: true
    validates :description, length: { maximum: 500 }

    after_validation :geocode

    private
        def geocode_string
            "#{postcode}"
        end
end

新用户视图(用户/注册):

<h2>Sign up</h2>

<% resource.build_profile %>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
    <%= devise_error_messages! %>

    <div><%= f.label :email %><br />
    <%= f.email_field :email %></div>

    <div><%= f.label :username %> <i>(this cannot be changed so choose wisely)</i><br />
    <%= f.text_field :username %></div>

    <div><%= f.label :password %><br />
    <%= f.password_field :password %></div>

    <div><%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation %></div>

    <%= f.fields_for resource.profile do |profile_form| %>
        <div><%= profile_form.label :full_name %><br />
        <%= profile_form.text_field :full_name %></div>

        <div><%= profile_form.label :birth_date %><br />
        <%= profile_form.date_select :birth_date, start_year: Time.now.year, end_year: Time.now.year - 80, order: [:day, :month, :year], prompt: { day: 'Choose day', month: 'Choose month', year: 'Choose year' } %></div>

        <div><%= profile_form.label :gender %><br />
        <%= profile_form.select :gender, { "Male" => '0', "Female" => '1' } %></div>

        <div><%= profile_form.label :postcode %><br />
        <%= profile_form.text_field :postcode %></div>

        <div><%= profile_form.label :description, "About you" %><br />
        <%= profile_form.text_area :description %></div>
    <% end %>

    <div><%= f.submit "Sign up" %></div>
<% end %>

<%= render :partial => "devise/shared/links" %>

除了更改after_update_path之外,注册控制器除了更改after_update_path之外还有其他标准:

class RegistrationsController < Devise::RegistrationsController

    protected

        def after_update_path_for(resource)
            users_control_panel_path
        end
end

我已经看过其他一些关于此的帖子,但它们似乎并不相关 - 如果我错了,请原谅我。有什么问题,如何解决?我特别困惑,因为它在我的本地机器上运行但在Heroku上运行(我已经迁移了数据库)。

修改

道歉,它在我的开发机器上不起作用 - 我添加了这个功能,它没有用,所以我在控制台中添加了细节而忘了重新访问它。

1 个答案:

答案 0 :(得分:0)

我已经通过替换

解决了这个问题
<%= f.fields_for resource.profile do |profile_form| %>

<%= f.fields_for :profile do |profile_form| %>