devise에서 여러 모델로 저장
7133 단어 nested_attributes루비Railsdevise
실현하고 싶은 일
devise의 계정 등록시에 2개의 모델에 기록시키고 싶다.
(사용자 정보 및 회사 정보)
왜?
다음 문제가 발생하기 때문입니다.
다음 문제가 발생하기 때문입니다.
Campany와 User 각각에서 User A 씨를 팔로우하고 싶었다.
문제점
팔로우 기능 구현 시 Campany(모델)와 User(모델)로 등록한 사용자는 같은 번호의 id를 가지고 있다.
┗Campany 페이지에서 계정 등록을 실시했을 때의 1번째의 유저 id는 1번.
┗User 페이지에서 계정 계정 등록을 했을 때의 1번째 사용자 id는 1번.
Follow 테이블에 follower로서 정보를 기록할 때 뒤의 연결을 위해 id를 남기고 싶지만 Campany와 User는 각각 다른 테이블에서 온 id 정보.
id 1이 되어 중복하기 때문에, 이 방법은 좋지 않았다.
생각한 해결 방법
법인(Campany)도 User로 간주 User 테이블에 등록한다.
다만 법인정보는 자식모델로서 Campanies 테이블에 등록한다.
준비
devise의 기본 설정 열에 임의 열 추가
devise의 registrations_controller.rb def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up,
keys: [:name, :category_id, campany_attributes: [:campany_name, :campany_logo, :category_id, :campany_url, :tel, :staff_last_name_kana, :staff_first_name_kana]])
end
campany_attributes: [:campany 레코드의 열 이름, :campany 레코드의 열 이름, ]
모델명 _attributes로 하는 것으로 부모 모델에 연결하고 있다.
(보충 : campany_attributes의 campany는 has_one 관계라면 단수, has_many라면 복수)
연관 설정
user.rb # userモデルの中でcampanyモデルへも同時書き込み
has_one :campany, inverse_of: :user
accepts_nested_attributes_for :campany
# Userモデル中でcampanyモデルへも書き込む
belongs_to :user, inverse_of: :campany
이번에는 new 액션은 user 등록으로 사용하고 있다.
법인 등록은 다른 화면으로 하고 싶었으므로 아래의 루트로 준비.
routes.rb get '/campany/new' => 'users/registrations#campany' ,as: :new_campany
참고로 한 기사에서는
@user.campany.build로 중첩 모델의 구조로 할 수 있다고 했지만, 이 기술이지만 잘 가지 않았다.
하기의 기법으로 하는 것으로 해결할 수 있었다.
또한 create 액션은 devise의 기능을 덮어쓰기 때문에 super 아래에 기술한다.
마지막으로 user.save로 하지 않으면 아이 모델(campany)에는 보존되지 않기 때문에 잊지 말고.
devise의 registrations_controller.rb # 企業の登録フォーム
def campany
@user = User.new
@user.build_campany
end
def create
super
user = User.new(configure_sign_up_params)
user.save
end
주의:
하위 모델에 데이터를 전달하는 방법은 다음과 같이 f.fields_for를 사용합니다.
상하와 같이 들여쓰기가 제대로 갖추어져 있으면 실현하고 싶은 레이아웃에 맞추어 User 모델, Campany 모델에 건네주는 데이터의 위치가 흩어져 있어도 좋다.
(부모 form은 form_for임)
campany.html.erb<h2><%= t('.sign_up') %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label "会社名" %><br />
<%= f.text_field :name, autocomplete: "off" %>
</div>
<%= f.fields_for :campany do |campany| %>
<div class="field">
<%= campany.label "会社URL" %><br />
<%= campany.text_field :campany_url, autocomplete: "off" %>
</div>
<div class="field">
<%= campany.label :tel %><br />
<%= campany.telephone_field :tel, autocomplete: "off" %>
</div>
<% end %>
<div class="field">
<%= f.label "カテゴリー" %><br />
<%= f.collection_select :category_id, Category.all, :id, :name, {prompt: "選択してください"}%>
</div>
<%= f.fields_for :campany do |campany| %>
<div class="field">
<%= campany.label "ご担当者様 姓(カナ)" %><br />
<%= campany.text_field :staff_last_name_kana, autocomplete: "off" %>
</div>
<div class="field">
<%= campany.label "ご担当者様 名(カナ)" %><br />
<%= campany.text_field :staff_first_name_kana, autocomplete: "off" %>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit t('.sign_up')%>
</div>
<% end %>
<%= render "devise/shared/links" %>
무사히 2개의 모델에 보존되었습니다.
실패한 것
registrations_controller 안에서 campany 메소드를 처음에는 new_campany라는 이름으로 하고 있었다.
오류로 new_campany_path? 라고 말했지만 그런 것은 아니다.
애초에 메소드명이 prefix 패스로 에러 문 토출한다는 것은 어떤 의미?
고민하는 것 3시간, 예약어 키워드가 고개를 끄덕였다.
설마 생각 메소드 이름을 바꾸자 뷰에 무사히 날아 줬다.
예약어에는 조심하자.
Reference
이 문제에 관하여(devise에서 여러 모델로 저장), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/params_bird/items/96922cae0c7a82ff157c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
법인(Campany)도 User로 간주 User 테이블에 등록한다.
다만 법인정보는 자식모델로서 Campanies 테이블에 등록한다.
준비
devise의 기본 설정 열에 임의 열 추가
devise의 registrations_controller.rb def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up,
keys: [:name, :category_id, campany_attributes: [:campany_name, :campany_logo, :category_id, :campany_url, :tel, :staff_last_name_kana, :staff_first_name_kana]])
end
campany_attributes: [:campany 레코드의 열 이름, :campany 레코드의 열 이름, ]
모델명 _attributes로 하는 것으로 부모 모델에 연결하고 있다.
(보충 : campany_attributes의 campany는 has_one 관계라면 단수, has_many라면 복수)
연관 설정
user.rb # userモデルの中でcampanyモデルへも同時書き込み
has_one :campany, inverse_of: :user
accepts_nested_attributes_for :campany
# Userモデル中でcampanyモデルへも書き込む
belongs_to :user, inverse_of: :campany
이번에는 new 액션은 user 등록으로 사용하고 있다.
법인 등록은 다른 화면으로 하고 싶었으므로 아래의 루트로 준비.
routes.rb get '/campany/new' => 'users/registrations#campany' ,as: :new_campany
참고로 한 기사에서는
@user.campany.build로 중첩 모델의 구조로 할 수 있다고 했지만, 이 기술이지만 잘 가지 않았다.
하기의 기법으로 하는 것으로 해결할 수 있었다.
또한 create 액션은 devise의 기능을 덮어쓰기 때문에 super 아래에 기술한다.
마지막으로 user.save로 하지 않으면 아이 모델(campany)에는 보존되지 않기 때문에 잊지 말고.
devise의 registrations_controller.rb # 企業の登録フォーム
def campany
@user = User.new
@user.build_campany
end
def create
super
user = User.new(configure_sign_up_params)
user.save
end
주의:
하위 모델에 데이터를 전달하는 방법은 다음과 같이 f.fields_for를 사용합니다.
상하와 같이 들여쓰기가 제대로 갖추어져 있으면 실현하고 싶은 레이아웃에 맞추어 User 모델, Campany 모델에 건네주는 데이터의 위치가 흩어져 있어도 좋다.
(부모 form은 form_for임)
campany.html.erb<h2><%= t('.sign_up') %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label "会社名" %><br />
<%= f.text_field :name, autocomplete: "off" %>
</div>
<%= f.fields_for :campany do |campany| %>
<div class="field">
<%= campany.label "会社URL" %><br />
<%= campany.text_field :campany_url, autocomplete: "off" %>
</div>
<div class="field">
<%= campany.label :tel %><br />
<%= campany.telephone_field :tel, autocomplete: "off" %>
</div>
<% end %>
<div class="field">
<%= f.label "カテゴリー" %><br />
<%= f.collection_select :category_id, Category.all, :id, :name, {prompt: "選択してください"}%>
</div>
<%= f.fields_for :campany do |campany| %>
<div class="field">
<%= campany.label "ご担当者様 姓(カナ)" %><br />
<%= campany.text_field :staff_last_name_kana, autocomplete: "off" %>
</div>
<div class="field">
<%= campany.label "ご担当者様 名(カナ)" %><br />
<%= campany.text_field :staff_first_name_kana, autocomplete: "off" %>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit t('.sign_up')%>
</div>
<% end %>
<%= render "devise/shared/links" %>
무사히 2개의 모델에 보존되었습니다.
실패한 것
registrations_controller 안에서 campany 메소드를 처음에는 new_campany라는 이름으로 하고 있었다.
오류로 new_campany_path? 라고 말했지만 그런 것은 아니다.
애초에 메소드명이 prefix 패스로 에러 문 토출한다는 것은 어떤 의미?
고민하는 것 3시간, 예약어 키워드가 고개를 끄덕였다.
설마 생각 메소드 이름을 바꾸자 뷰에 무사히 날아 줬다.
예약어에는 조심하자.
Reference
이 문제에 관하여(devise에서 여러 모델로 저장), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/params_bird/items/96922cae0c7a82ff157c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up,
keys: [:name, :category_id, campany_attributes: [:campany_name, :campany_logo, :category_id, :campany_url, :tel, :staff_last_name_kana, :staff_first_name_kana]])
end
user.rb
# userモデルの中でcampanyモデルへも同時書き込み
has_one :campany, inverse_of: :user
accepts_nested_attributes_for :campany
# Userモデル中でcampanyモデルへも書き込む
belongs_to :user, inverse_of: :campany
이번에는 new 액션은 user 등록으로 사용하고 있다.
법인 등록은 다른 화면으로 하고 싶었으므로 아래의 루트로 준비.
routes.rb
get '/campany/new' => 'users/registrations#campany' ,as: :new_campany
참고로 한 기사에서는
@user.campany.build로 중첩 모델의 구조로 할 수 있다고 했지만, 이 기술이지만 잘 가지 않았다.
하기의 기법으로 하는 것으로 해결할 수 있었다.
또한 create 액션은 devise의 기능을 덮어쓰기 때문에 super 아래에 기술한다.
마지막으로 user.save로 하지 않으면 아이 모델(campany)에는 보존되지 않기 때문에 잊지 말고.
devise의 registrations_controller.rb
# 企業の登録フォーム
def campany
@user = User.new
@user.build_campany
end
def create
super
user = User.new(configure_sign_up_params)
user.save
end
주의:
하위 모델에 데이터를 전달하는 방법은 다음과 같이 f.fields_for를 사용합니다.
상하와 같이 들여쓰기가 제대로 갖추어져 있으면 실현하고 싶은 레이아웃에 맞추어 User 모델, Campany 모델에 건네주는 데이터의 위치가 흩어져 있어도 좋다.
(부모 form은 form_for임)
campany.html.erb
<h2><%= t('.sign_up') %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label "会社名" %><br />
<%= f.text_field :name, autocomplete: "off" %>
</div>
<%= f.fields_for :campany do |campany| %>
<div class="field">
<%= campany.label "会社URL" %><br />
<%= campany.text_field :campany_url, autocomplete: "off" %>
</div>
<div class="field">
<%= campany.label :tel %><br />
<%= campany.telephone_field :tel, autocomplete: "off" %>
</div>
<% end %>
<div class="field">
<%= f.label "カテゴリー" %><br />
<%= f.collection_select :category_id, Category.all, :id, :name, {prompt: "選択してください"}%>
</div>
<%= f.fields_for :campany do |campany| %>
<div class="field">
<%= campany.label "ご担当者様 姓(カナ)" %><br />
<%= campany.text_field :staff_last_name_kana, autocomplete: "off" %>
</div>
<div class="field">
<%= campany.label "ご担当者様 名(カナ)" %><br />
<%= campany.text_field :staff_first_name_kana, autocomplete: "off" %>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password %>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit t('.sign_up')%>
</div>
<% end %>
<%= render "devise/shared/links" %>
무사히 2개의 모델에 보존되었습니다.
실패한 것
registrations_controller 안에서 campany 메소드를 처음에는 new_campany라는 이름으로 하고 있었다.
오류로 new_campany_path? 라고 말했지만 그런 것은 아니다.
애초에 메소드명이 prefix 패스로 에러 문 토출한다는 것은 어떤 의미?
고민하는 것 3시간, 예약어 키워드가 고개를 끄덕였다.
설마 생각 메소드 이름을 바꾸자 뷰에 무사히 날아 줬다.
예약어에는 조심하자.
Reference
이 문제에 관하여(devise에서 여러 모델로 저장), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/params_bird/items/96922cae0c7a82ff157c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(devise에서 여러 모델로 저장), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/params_bird/items/96922cae0c7a82ff157c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)