ProgramingTip

여러 "사용자"모델을 고안하고

bestdevel 2020. 10. 24. 11:21
반응형

여러 "사용자"모델을 고안하고


저는 Rails 3.2를 사용하고 2.0을 고안 한 Rails를 처음 사용합니다.

요구 사항

다음을 달성하고 싶습니다.

  • 2 개 이상의 "사용자"모델이 있습니다. 회원, 고객, 관리자
  • 모든 모델은 일부 필수 필드 (예 : 이메일 및 비밀번호)를 공유합니다.
  • 각 모델에는 고유 한 필드가있을 수 있습니다 (예 : 고객 전용 회사)
  • 일부 필드는 공유 할 수 있습니다. 유효성이 동일하지 않습니다. (예 : 고객에게는 필요하지만 회원에게는 선택 사항).
  • 모든 필드는 등록 과정에서 제출해야합니다.
  • 로그인 양식은 고유해야합니다.

가능한 해결책

나는 꽤 오랫동안 StackOverflow를 검색하고 검색했지만 나에게는 아무것도 옳지 않은 것입니다 (나는 Java 사람입니다, 죄송합니다 :). 지금은 꽤 혼란 스럽습니다. 두 가지 조치이 나.

단일 장치 사용자

그게 가장 빈번한 대답입니다. 기본 장치 사용자를 생성하고 구성원-> 사용자와 고객-> 사용자 관계를 생성하기 만하면됩니다. 여기서 내 관심사는 각 모델에 대한 일련의 등록 프로세스를 어떻게 달성 할 수 있는가입니다. 나는 다른 것을 시도했지만 모두 엉망으로 끝났습니다!

여러 장치 사용자

이것은 사용자 정의 등록 프로세스를 해결하고 나에게 옳은 것처럼 보이지만 고유 한 로그인 양식은 차단기입니다. Devise :: Models :: Authenticatable.find_for_authentication (conditions)을 재정의 할 제안 제안하는 SO ( Devise-login from two model ) 에 대한 답변을 찾았습니다 . 복잡해 보이지만 (?) Rails가 처음 접 찍 때문에 작동 할 수 있는지 알고 싶습니다.

조언 해 주셔서 감사합니다!


Java guy =)에 오신 것을 환영합니다. Rails 세계를 즐기시기 바랍니다. 간단히, 문제를 해결 비용 다음 두 가지 솔루션이 있습니다.

  1. 각 사용자에 대해 데이터베이스 및 해당 모델에 테이블을 만듭니다.
  2. 데이터베이스에 단일 테이블을 만들고 각 사용자 유형에 대해 모델을 만듭니다. 이를 단일 테이블 상속 (STI)이라고합니다.

어느 것을 선택할까요? 역할의 공통 속성에 따라 증가합니다. 거의 일반적이고 (예를 들어 모두 이름, 이메일, 모바일 등) 몇 가지 속성이 다른 경우 STI 솔루션을 적극 권장합니다.

STI는 어떻게? 1. 간단히 명령을 사용하여 사용자 모델과 테이블을 생성합니다. rails generate devise User2. type마이그레이션을 사용하여 데이터베이스 명명의 사용자 테이블에 고급 데이터 유형으로 된 열을 추가 합니다. 3. 각 사용자 유형에 대해 모델을 만듭니다 (예 rails g model admin:) 4. 관리자 클래스가 사용자 모델에서 상속합니다.

class Admin < User
end

그게 다 끝났어 =) ... Yupeee

관리자를 만들려면 Admin.create(...)점이 관리자 속성 (예 : 이메일, 이름, ...

질문 이 당신 에게도 도움 될 생각합니다


나는 모든 종류의 접근 방식을 시도한 후 다형성 역할에 단일 사용자 모델을 사용하여 당신과 입장에 있습니다. 이 단일 로그인을 달성하는 가장 간단한 방법 인 것입니다.

사용자 모델에는 로그인 관련 정보 만됩니다.

역할 모델은 각 역할에 풍부한 필드와 역할에 다른 연관을 저장합니다.

새 등록은 ID 컨트롤러를 통해 각 사용자 유형 (역할)에 맞게 사용자 정의 된 다음 사용자에 대한 중첩 된 속성을 구축합니다.

class User < ActiveRecord::Base
    #... devise code ...
    belongs_to :role, :polymorphic => true
end

class Member < ActiveRecord::Base
    attr_accessible :name, :tel, :city  #etc etc....
    attr_accessible :user_attributes #this is needed for nested attributes assignment

    #model specific associations like  
    has_many :resumes

    has_one :user, :as => :role, dependent: :destroy
    accepts_nested_attributes_for :user
end 

경로 멤버 모델의 일반적인 항목입니다.

resources :members
#maybe make a new path for New signups, but for now its new_member_path

컨트롤러-중첩 된 속성에 build_user가 필요합니다.

#controllers/members_controller.rb
def new
    @member = Member.new
    @member.build_user
end

def create
    #... standard controller stuff
end

조회수 / 회원 / new.html.erb

<h2>Sign up for new members!</h2>
<%= simple_form_for @member do |f| %>

    # user fields
    <%= f.fields_for :user do |u| %>
      <%= u.input :email, :required => true, :autofocus => true %>
      <%= u.input :password, :required => true %>
      <%= u.input :password_confirmation, :required => true %>
    <% end %>

    # member fields
    <%= f.input :name %>
    <%= f.input :tel %>
    <%= f.input :city %>

    <%= f.button :submit, "Sign up" %>
<% end %>

nested_form gem에 도달 할 필요가 점을 지적하고 싶습니다. 사용자는 한 가지 유형의 역할에만 속할 수 있습니다.


갈 방법을 찾았고 지금까지 매우 만족합니다. 다른 사람들을 위해 여기에서 설명하겠습니다.

저는 사용자 "사용자"클래스로. 내 문제는 각 의사 모델에 대한 프로세스 등록 프로세스를 달성하는 것이 었습니다.

모델 / 사용자 .rb :

class User < ActiveRecord::Base
  devise :confirmable,
       :database_authenticatable,
       :lockable,
       :recoverable,
       :registerable,
       :rememberable,
       :timeoutable,
       :trackable,
       :validatable

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

  as_enum :role, [:administrator, :client, :member]
  validates_as_enum :role
  ## Rails 4+ for the above two lines
  # enum role: [:administrator, :client, :member]

end

그런 다음 재정의 된 컨트롤러가있는 두 개의 등록 경로를 갖도록 http://railscasts.com/episodes/217-multistep-formshttp://pastie.org/1084054받았습니다 .

구성 / route.rb :

get  'users/sign_up'   => 'users/registrations#new',        :as => 'new_user_registration'

get  'clients/sign_up' => 'users/registrations#new_client', :as => 'new_client_registration'
post 'clients/sign_up' => 'users/registrations#create',     :as => 'client_registration'

get  'members/sign_up' => 'users/registrations#new_member', :as => 'new_member_registration'
post 'members/sign_up' => 'users/registrations#create',     :as => 'member_registration'

컨트롤러 / 사용자 / registrations_controller.rb :

각 단계에서 유효성을 검사 할 필드를 알고있는 마법사 클래스를 만들었습니다.

class Users::RegistrationsController < Devise::RegistrationsController

    # GET /resource/sign_up
    def new
        session[:user] ||= { }
        @user = build_resource(session[:user])
        @wizard = ClientRegistrationWizard.new(current_step)

        respond_with @user
    end

    # GET /clients/sign_up
    def new_client
        session[:user] ||= { }
        session[:user]['role'] = :client
        @user = build_resource(session[:user])
        @wizard = ClientRegistrationWizard.new(current_step)

        render 'new_client'
    end

    # GET /members/sign_up
    def new_member
      # same
    end

    # POST /clients/sign_up
    # POST /members/sign_up
    def create
        session[:user].deep_merge!(params[:user]) if params[:user]
        @user = build_resource(session[:user])
        @wizard = ClientRegistrationWizard.new(current_step)

        if params[:previous_button]
            @wizard.previous
        elsif @user.valid?(@wizard)
            if @wizard.last_step?
                @user.save if @user.valid?
            else
                @wizard.next
            end
        end

        session[:registration_current_step] = @wizard.current_step

        if @user.new_record?
            clean_up_passwords @user
            render 'new_client'
        else
            #session[:registration_current_step] = nil
            session[:user_params] = nil

            if @user.active_for_authentication?
                set_flash_message :notice, :signed_up if is_navigational_format?
                sign_in(:user, @user)
                respond_with @user, :location => after_sign_up_path_for(@user)
            else
                set_flash_message :notice, :"signed_up_but_#{@user.inactive_message}" if is_navigational_format?
                expire_session_data_after_sign_in!
                respond_with @user, :location => after_inactive_sign_up_path_for(@user)
            end
        end

    end

    private

    def current_step
        if params[:wizard] && params[:wizard][:current_step]
            return params[:wizard][:current_step]
        end
        return session[:registration_current_step]
    end

end

내 견해는 다음과 가변적이다.

  • new.rb
  • new_client.rb 마법사 단계에 따라 부분 포함 :
    • _new_client_1.rb
    • _new_client_2.rb
  • new_member.rb 마법사 단계에 따라 부분 포함 :
    • _new_member_1.rb
    • _new_member_2.rb

그래서 무엇이 잘못 되었나요? 그냥 실행하고 rails g devise:views [model_name], 각 등록 양식을 사용자 정의하고 config/initializer/devise.rb그냥 넣으십시오 config.scoped_views = true.

참고 URL : https://stackoverflow.com/questions/9472852/devise-and-multiple-user-models

반응형