고안 등록 컨트롤러 재정의


236

다른 모델을 기반으로하는 가입 양식에 필드를 추가했습니다 . gory 세부 사항을 위해 고안 모델중첩 속성을 사용하는 방법을 참조 하십시오. 이 부분은 잘 작동합니다.

문제는 내가 저장할 Activerecord::UnknownAttributeError때이 필드 (회사) 와 함께 고안하여 제공되는 등록 컨트롤러의 작성 작업에서 실패하는 것입니다 .

등록 컨트롤러를 재정의해야한다고 가정하거나 더 나은 방법으로 접근해야합니까?


1
사실 이것에 전체 블로그 포스트를 작성 jacopretorius.net/2014/03/...
자코 프리 토 리우스에게

답변:


354

귀하의 양식에서 사용자 모델에 속하지 않은 대량 할당 또는 중첩 모델을 통해 다른 속성을 전달합니까?

그렇다면이 인스턴스에서 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 

그리고 다음을 사용하여 기본값 대신 해당 컨트롤러를 사용하도록 고안하십시오.

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

3
그러나 고안 디바이스에서 뷰에 대한 고안을 어떻게 확인합니까? 나는 이것을 시도하고 있지만 "sign_in_and_redirect (resource_name, resource)"와 같은 방법을 고안하여 템플릿에 대한 뷰를 찾고 있습니다.
AnApprentice

7
고안 뷰를 사용자 정의하려면 먼저 생성해야하며 보석에서 뷰를로드하기 전에 뷰 폴더가 뷰 폴더를 확인합니다. Rails 3에서는 다음 rails generate devise:views과 같습니다. Rails 2에서는 다음 과 같습니다.script/generate devise:views
theTRON

2
위의 핵은 레일 2에서 작동하는 버전 인 1.0.8에서 작동하지 않습니다.
William Yeung

18
이와 같이 Devise 컨트롤러를 재정의하는 경우 모든 뷰를 app / views / devise / registrations에서 app / views / registrations / (복사하는 컨트롤러에 대한 변경)로 복사해야합니다.
Jamie Cobbett

31
또는 고안 뷰를 그대로두고에 추가 paths.app.views << "app/views/devise"할 수 있습니다 config/application.rb.
theTRON

66

네임 스페이스를 사용하여 Devise 컨트롤러 및보기를 재정의하는보다 체계적이고 체계적인 방법 :

다음 폴더를 작성하십시오.

app/controllers/my_devise
app/views/my_devise

재정의하려는 모든 컨트롤러를 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 

이에 따라 경로를 변경하십시오.

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

필요한 모든보기를 app/views/my_deviseDevise gem 폴더에 복사하거나 사용하고 rails generate devise:views, 재정의하지 않는보기를 삭제하고 devise폴더 이름을 바꿉니다 my_devise.

이렇게하면 모든 것을 깔끔하게 두 개의 폴더로 구성 할 수 있습니다.


1
이것은 내가 취하는 접근 방식과 유사하지만 createDevise의 방법에 어떤 사용자 지정 논리를 덮어 쓸지 모르겠습니다. 내가 수정 한 비계 제작 컨트롤러는 훌륭하게 작동하지만 Devise의 resource비즈니스에서 어떻게 작동하게 합니까?
Kyle Carlson

@Vincent 감사합니다-한 가지 방법 만 재정의하려면 재정의하려는 방법 만 작성합니까? 다른 모든 기능이 정상적으로 작동합니까? 귀하의 도움에 감사드립니다
BKSpurgeon

MyDevise::RegistrationsController < Devise::RegistrationsController순환 종속성 오류를 만듭니다. 내가 뭔가 잘못하고 있습니까?
ianrandmckenzie

34

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

내 견해 : 'devise / 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" %>

3
뷰에서 모델로 빌드 로직을 이동하는 것이 더 깨끗합니다. stackoverflow.com/questions/3544265#3764837
meleyal

고안 컨트롤러를 생성했으며 이제 사용자가 가입을 클릭하면 컨트롤러 작업 생성이 트리거됩니다. Devise를 사용하여 비밀번호를 암호화하고 비밀번호 및 기타 필드의 백엔드 검사를 수행 할 수있는 방법이 있습니까 (예 : 재정의 / 일부 코드)? 모델 데이터베이스에 저장 하시겠습니까?
HP

resource클래스 인스턴스 변수 대신 뷰에서 로컬 변수 에 어떻게 액세스 할 수 @resource있습니까?
Chloe

12

고안 커스터마이징을 위해 뷰와 컨트롤러를 생성 할 수 있습니다.

사용하다

rails g devise:controllers users -c=registrations

rails g devise:views 

gem에서 애플리케이션으로 특정 컨트롤러 및 뷰를 복사합니다.

다음으로, 라우터에게이 컨트롤러를 사용하도록 지시하십시오.

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

11

매우 간단한 방법 터미널과 다음 유형으로 이동하십시오.

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

이제 route.rb 파일에

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

다른 컨트롤러도 추가 할 수 있습니다. 이것은 사용자 폴더의 컨트롤러와 사용자 폴더의 뷰를 사용하도록 고안 될 것입니다.

이제 원하는대로보기를 사용자 정의하고 컨트롤러 / 사용자 폴더의 컨트롤러에 로직을 추가 할 수 있습니다. 즐겨 !

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.