Ruby-on-rails 覆盖设计注册控制器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3546289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:05:39  来源:igfitidea点击:

Override devise registrations controller

ruby-on-railsdevise

提问by Craig McGuff

I have added a field to the sign-up form that is based on a different model, see How do I use nested attributes with the devise modelfor the gory details. This part is working fine.

我已向基于不同模型的注册表单添加了一个字段,请参阅如何将嵌套属性与设计模型一起使用以获取详细信息。这部分工作正常。

The problem now is when I save, it is failing in the create action of the registrations controller that is supplied by devise with an Activerecord::UnknownAttributeErroron this field (company).

现在的问题是,当我保存时,它在由设备提供的注册控制器的创建操作中失败Activerecord::UnknownAttributeError(该字段(公司))。

I am assuming I need to override the registrations controller, or is there a better/easier way I should be approaching this?

我假设我需要覆盖注册控制器,或者有更好/更简单的方法来解决这个问题吗?

回答by theTRON

In your form are you passing in any other attributes, via mass assignment that don't belong to your user model, or any of the nested models?

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

If so, I believe the ActiveRecord::UnknownAttributeError is triggered in this instance.

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

Otherwise, I think you can just create your own controller, by generating something like this:

否则,我认为您可以通过生成如下内容来创建自己的控制器:

# 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 

And then tell devise to use that controller instead of the default with:

然后告诉 devise 使用该控制器而不是默认控制器:

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

回答by Vincent

A better and more organized way of overriding Devise controllers and views using namespaces:

使用命名空间覆盖设计控制器和视图的更好、更有条理的方法:

Create the following folders:

创建以下文件夹:

app/controllers/my_devise
app/views/my_devise

Put all controllers that you want to override into app/controllers/my_devise and add MyDevisenamespace to controller class names. Registrationsexample:

将您要覆盖的所有控制器放入 app/controllers/my_devise 并将MyDevise命名空间添加到控制器类名称。Registrations例子:

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

  ...

  def create
    # add custom create logic here
  end

  ...    

end 

Change your routes accordingly:

相应地更改您的路线:

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

Copy all required views into app/views/my_devisefrom Devise gem folder or use rails generate devise:views, delete the views you are not overriding and rename devisefolder to my_devise.

复制所有需要的视图到app/views/my_devise从设计宝石的文件夹或应用rails generate devise:views,删除你不重写的意见和重命名devise文件夹my_devise

This way you will have everything neatly organized in two folders.

通过这种方式,您可以将所有内容整齐地组织在两个文件夹中。

回答by thb

I believe there is a better solution than rewrite the RegistrationsController. I did exactly the same thing (I just have Organization instead of Company).

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

If you set properly your nested form, at model and view level, everything works like a charm.

如果您在模型和视图级别正确设置嵌套表单,一切都会像魅力一样工作。

My User model:

我的用户模型:

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

My Organization Model:

我的组织模式:

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

My view : 'devise/registrations/new.html.erb'

我的观点:'设计/注册/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" %>

回答by user1201917

You can generate views and controllers for devise customization.

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

Use

rails g devise:controllers users -c=registrations

and

rails g devise:views 

It will copy particular controllers and views from gem to your application.

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

Next, tell the router to use this controller:

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

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

回答by Pradeep Sapkota

Very simple methods Just go to the terminal and the type following

非常简单的方法 只需转到终端并键入以下内容

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

Next to use custom views

接下来使用自定义视图

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

now in your route.rb file

现在在你的 route.rb 文件中

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

You can add other controllers too. This will make devise to use controllers in users folder and views in users folder.

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

Now you can customize your views as your desire and add your logic to controllers in controllers/users folder. Enjoy !

现在,您可以根据需要自定义视图并将逻辑添加到控制器/用户文件夹中的控制器。享受 !