覆盖设计注册控制器

我已经在注册表单中添加了一个基于不同模型的字段,详见我如何使用嵌套的属性与设计模型。这部分工作正常。

现在的问题是,当我保存时,它在注册控制器的创建动作中失败,注册控制器是由这个字段(company)上的Activerecord::UnknownAttributeError提供的。

我假设我需要覆盖注册控制器,或者有一个更好/更容易的方法,我应该接近这个?

190858 次浏览

在您的表单中,您是否传递了任何其他属性,通过大量分配,不属于您的用户模型,或任何嵌套模型?

如果是这样,我相信ActiveRecord::UnknownAttributeError在这个实例中被触发。

否则,我认为你可以创建你自己的控制器,通过生成像这样的东西:

# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def new
super
end


def create
# add custom create logic here
end


def update
super
end
end

然后告诉design使用那个控制器而不是默认的:

# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}

我相信有一个比重写RegistrationsController更好的解决方案。我做了完全相同的事情(我只是有组织而不是公司)。

如果您在模型和视图级别正确地设置了嵌套表单,那么一切都很顺利。

我的用户模型:

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


has_many :owned_organizations, :class_name => 'Organization', :foreign_key => :owner_id


has_many :organization_memberships
has_many :organizations, :through => :organization_memberships


# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :username, :owned_organizations_attributes


accepts_nested_attributes_for :owned_organizations
...
end

我的组织模式:

class Organization < ActiveRecord::Base
belongs_to :owner, :class_name => 'User'
has_many :organization_memberships
has_many :users, :through => :organization_memberships
has_many :contracts


attr_accessor :plan_name


after_create :set_owner_membership, :set_contract
...
end

我的观点:' designing /registrations/new.html.erb'

<h2>Sign up</h2>


<% resource.owned_organizations.build if resource.owned_organizations.empty? %>
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>


<p><%= f.label :name %><br />
<%= f.text_field :name %></p>


<p><%= f.label :email %><br />
<%= f.text_field :email %></p>


<p><%= f.label :username %><br />
<%= f.text_field :username %></p>


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


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


<%= f.fields_for :owned_organizations do |organization_form| %>


<p><%= organization_form.label :name %><br />
<%= organization_form.text_field :name %></p>


<p><%= organization_form.label :subdomain %><br />
<%= organization_form.text_field :subdomain %></p>


<%= organization_form.hidden_field :plan_name, :value => params[:plan] %>


<% end %>


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


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

使用命名空间重写design控制器和视图的更好、更有组织的方法:

创建以下文件夹:

app/controllers/my_devise
app/views/my_devise

将你想要重写的所有控制器放到app/controllers/ my_designing中,并将MyDevise命名空间添加到控制器类名中。Registrations例子:

# app/controllers/my_devise/registrations_controller.rb
class MyDevise::RegistrationsController < Devise::RegistrationsController


...


def create
# add custom create logic here
end


...


end

相应地改变你的路线:

devise_for :users,
:controllers  => {
:registrations => 'my_devise/registrations',
# ...
}

将所有需要的视图从设计gem文件夹复制到app/views/my_devise或使用rails generate devise:views,删除你没有覆盖的视图,并将devise文件夹重命名为my_devise

这样你就可以把所有的东西整齐地组织在两个文件夹里。

您可以为设计定制生成视图和控制器。

使用

rails g devise:controllers users -c=registrations

而且

rails g devise:views

它会复制特定的控制器和视图从gem到你的应用程序。

接下来,告诉路由器使用这个控制器:

devise_for :users, :controllers => {:registrations => "users/registrations"}
非常简单的方法 只要转到终端,输入

rails g devise:controllers users //This will create devise controllers in controllers/users folder

接下来使用自定义视图

rails g devise:views users //This will create devise views in views/users folder

现在在你的路线上。rb文件

devise_for :users, controllers: {
:sessions => "users/sessions",
:registrations => "users/registrations" }

您也可以添加其他控制器。这将使设计使用用户文件夹中的控制器和用户文件夹中的视图。

现在你可以根据需要定制视图,并将你的逻辑添加到controllers/users文件夹中的控制器中。 享受吧! < / p >

我来到这里是因为我试图自定义注册时设计许可的参数。

我使用这个答案创建自定义控制器,然后尝试允许属性timezone,如下所示:

def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:timezone])
end

它没有工作,直到我取消注释在生成的控制器顶部的行:

before_action :configure_sign_up_params, only: [:create]