迁移后添加新列时出现意外的NoMethodError

时间:2014-08-02 05:25:19

标签: ruby-on-rails-4 devise sti

我有一个player模型继承自user模型,以与第三个模型(coach共享身份验证逻辑(设计),也继承自用户)。

class User < ActiveRecord::Base
end
class Player < User
end
class Coach < User
end

当玩家注册时,我正在尝试向player表添加一个字段,因此我创建了一个迁移

rails g migration AddClubCoachEmailToPlayer club_coach_email:string

然后运行迁移

rake db:migrate

为文件

class AddClubCoachEmailToPlayer < ActiveRecord::Migration
  def change
    add_column :players, :club_coach_email, :string
  end
end

架构符合预期

  create_table "players", force: true do |t|
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "club_coach_email"
  end

现在,我需要将字段添加到/ views / players / registrations / new

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

  <div><%= f.label :position %><br />
    <%= f.radio_button(:position, "Striker") %> Striker
    <%= f.radio_button(:position, "Midfielder") %> Midefielder
    <%= f.radio_button(:position, "Defender") %> Defender
  </div>
  <div><%= f.label :club_coach_email %><br />
  <%= f.email_field :club_coach_email %></div>

  <div><%= f.label :profile_name %><br />
  <%= f.text_field :profile_name %></div>

 #...

我从设计wiki中通过这种技术消毒params;在lib / player_sanitizer.rb中我添加了新字段。

class PlayerParameterSanitizer < Devise::ParameterSanitizer
  private
  def sign_up
    default_params.permit(:first_name, :last_name, :profile_name, :password, :password_confirmation, :email, :grad_year, :position, :club_team, :formation, :club_coach_email)
  end
  def account_update
    default_params.permit(:first_name, :last_name, :profile_name, :password, :password_confirmation, :email, :grad_year, :position, :club_team, :formation)
  end
end

这就是我的应用程序控制器的样子

class ApplicationController < ActionController::Base
  def after_sign_in_path_for(user)
    dashboard_path
  end

  protected
  def devise_parameter_sanitizer
    if resource_class == Player
      PlayerParameterSanitizer.new(Player, :player, params)
    elsif resource_class == Coach
      CoachParameterSanitizer.new(Coach, :coach, params)
    else
      super
    end    
  end 
end

但是,我必须错过一些步骤,因为当我导航到/ players / sign_up时,我得到NoMethodError in Players::Registrations#new

undefined method `club_coach_email' for #<Player:0x00000109296be8>

Obvioulsy,这里是跟踪指向的地方

<%= f.radio_button(:position, "Defender") %> Defender
 </div>
 <div><%= f.label :club_coach_email %><br />
 <%= f.email_field :club_coach_email %></div>

 <div><%= f.label :profile_name %><br />
 <%= f.text_field :profile_name %></div>

我在这里似乎不明白?

1 个答案:

答案 0 :(得分:0)

至于我,你做得太复杂了。根据您提供的信息,这三种不同的用户类型之间没有不同的功能,因此更容易使所有这些不是通过继承而是使用devise roles

通过这种方式,您将拥有一个具有三种不同角色的用户模型(用户,玩家,教练)。

或者还有其他方式 - 在“设计方式”中使用不同的模型: rails g devise User + rails g devise Player + rails g devise Coach

在此之后,您将获得三个几乎独立的模型,每个模型都具有所有设计功能和方法(例如:player_signed_in?current_coachauthenticate_player!等。)