質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

5973閲覧

railsでユーザー新規登録(devise)をしたとき1:1の関係にある他のテーブルにデータを自動作成したい

zendendo

総合スコア43

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2017/10/30 02:02

編集2017/11/10 07:19

###前提・実現したいこと
ruby(rails)で、銀行みたいなアプリをつくっています。
銀行のように一人の顧客が一つだけ口座を開設できるのと同じように・・・

ユーザーが新規会員登録したと同時に、
ユーザーモデルと1:1の関係にあるアカウントモデルに
レコードを自動作成をしたいのですが、よくわからず困っています。

もう少し具体的に言うとこんな感じです。

ユーザーがdeviseでメールアドレスとパスワードを入力して会員登録を済ませます。
そして会員登録が成功したとき、自動的にアカウントが作成されます。
このとき、ユーザーは何も入力せずにアカウントテーブルに、
「user_id(ユーザーと紐づく為の外部キー)」
「アカウント番号(他のアカウント番号と被らないランダムな11桁の番号)」
「残高(デフォルトで0.00)」
という内容がつくられるようにしたいと考えています。

この場合、どんな実装をすればいいのか教えて頂ければ幸いです。

###試しに書いたソースコード
model部分だけ書いてみました。

class User < ApplicationRecord has_one :account before_create :build_default_account # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable private def build_default_account build_account true end end
class Account < ApplicationRecord belongs_to :user validates :user_id, presence:true def load_defaults #もしDBに保存されていない(新規登録)ならば、口座番号をランダムに作成する #もしDBに保存されていない(新規登録)ならば、残高を0にする。 if self.new_record? self.account_number = SecurRandom.uuid self.balance = 0.00 end end end

###補足情報(言語/FW/ツール等のバージョンなど)
Rails 5.1.3
ruby 2.4.1
devise (4.3.0)

###アドバイスを参考に変更したファイル内容を追記(成功)
以下には、アドバイスを参考にコードを修正し、最終的に成功したコード内容を追記しておきます。

model.user.rbを編集。

class User < ApplicationRecord has_one :account # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable end

model/account.rbを編集。

class Account < ApplicationRecord belongs_to :user end

app/controllersにhoges_controller.rbを作成して編集。

class HogesController < ApplicationController def index @account = Account.all end def new @user = User.new end def create @user = User.new(user_params) @user.build_account #Userの子要素であるアカウントを関連付ける # インカムアカウントテーブルのaccount_numberのカラムに代入する @user.account.account_number = SecureRandom.random_number(1000000000000) @user.account.balance = 0 @user.save redirect_to '/hoges/index' end private def user_params params.require(:user).permit(:password, :email) end def account_params params.require(:account).permit(:account_number, :balance) end end

/app/views/hogeにindex.html.erbを作成して編集。

<p>index.html.erb</p> <p>作成画面</p> <%= form_for(@user) do |f| %> <div class= "field"> <%= f.label :email %> <%= f.email_field :email %> <%= f.label :password %> <%= f.password_field :password %> <%= f.submit "会員登録" %> <% end %> </div>

routes.rbに追記する。

Rails.Application.routes.draw do ・・・ get 'hoges/index' get 'hoges/new' post 'users' => 'hoges#create' ・・・ end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

以下のやり方でも解決することができます。
1.モデルの関連付けを行う
user(ユーザー)モデルは、basic_income_account(口座)モデルを一つ保有している1:1の関係にある。

#deviseで管理しているuserのモデル class User < ApplicationRecord has_one :basic_income_account devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable end
class BasicIncomeAccount < ApplicationRecord #BasicIncomeAccountはuserから1:1の関係で所有されている belongs_to :user end

2.deviseのコントローラを作成し編集(カスタマイズ)する
以下のコマンドでdeviseのコントローラを作成する。
rails g devise:controllers users

すると、app/controllers/usersに
deviseのコントローラファイルが作成されます。
この中には、いくつかのコントローラファイルがあるのですが、新規登録を司っている
registrations_controller.rbを編集します。
書き加える部分は、def createの部分。
1:1で親モデルが子モデルにデータをつくる(has_one)関係の場合、
resource.build_basic_income_account
変数.build_小文字単数形でかくモデル名
とすれば、いい。
あとは、
「変数.小文字単数系でかくモデル名.カラム名 = 記録したい値の処理」
という形で、子モデルに記録したいものを書いていき、
最後に、
変数.save
と書けばいい。

class Users::RegistrationsController < Devise::RegistrationsController # before_action :configure_sign_up_params, only: [:create] # before_action :configure_account_update_params, only: [:update] # GET /resource/sign_up def new super end # POST /resource def create super #Userの子要素であるbasic_income_accountを関連付ける resource.build_basic_income_account #同時につくられるBI口座の登録内容 require 'securerandom' n = 12 resource.basic_income_account.account_number = format("%0#{n}d", SecureRandom.random_number(10**n)) resource.basic_income_account.balance = 0 resource.save end # GET /resource/edit # def edit # super # end # PUT /resource # def update # super # end # DELETE /resource # def destroy # super # end # GET /resource/cancel # Forces the session data which is usually expired after sign # in to be expired now. This is useful if the user wants to # cancel oauth signing in/up in the middle of the process, # removing all OAuth session data. # def cancel # super # end # protected # If you have extra params to permit, append them to the sanitizer. # def configure_sign_up_params # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) # end # If you have extra params to permit, append them to the sanitizer. # def configure_account_update_params # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) # end # The path used after sign up. # def after_sign_up_path_for(resource) # super(resource) # end # The path used after sign up for inactive accounts. # def after_inactive_sign_up_path_for(resource) # super(resource) # end end

3.編集したdeviseのコントローラが使えるようにルーティング設定を行う

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

これで、さっきカスタマイズしたdeviseのコントローラ(registrations_controller.rb)を読み取ってくれます。
以上の設定をすることで、deviseで新規会員登録をしたと同時に、
1:1の関係にあるBasicIncomeAccount(口座)モデルにもレコードを作成保存することができます。

投稿2017/12/13 23:51

編集2017/12/13 23:56
zendendo

総合スコア43

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

前提条件として以下を上げます。

1.View側にはAccountの値を持たせず、controller側に値を書く
2.Deviseを利用ということでしたが、新規登録画面(hoge.html.erb)を別に作っているものとする

model/user.rb

class User < ApplicationRecord has_one :account # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable end

model/account.rb

class Account < ApplicationRecord belongs_to :user end

controller/hoge_controller.rb

class hogesController < ApplicationController def index @user = User.new end def create @user = User.new(user_params) @user.build_account # Userの子要素であるAccountを関連付ける @user.account.account_number = ランダム数字を入れる # Accountテーブルのaccount_numberのカラムに代入する @user.account.balance = 0.00初期金額 @user.save end private def user_params params.require(:user).permit(:password, :email) end end

model側に書かれていますが、Controller側に書くようにしてください。

※参考
https://qiita.com/seimiyajun/items/cd398f741ac108cf11f8

投稿2017/11/01 07:30

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zendendo

2017/11/02 07:13

gomasioさん、回答して下さりありがとうございます。 アドバイスを参考に、上記に追記した内容にしてみたのですが、 http://localhost:3000/hoges/index(新規登録画面)にアクセスすると ActionController::UnknownFormat in HogesController#index というエラーが発生してしまいました。
退会済みユーザー

退会済みユーザー

2017/11/02 07:29

フォーマットがないって言われてるので、Controllerの中にindexを作ってあげるか&view側にindexファイルを作ってあげてください。
zendendo

2017/11/02 07:54

app/controller/hoges_controller.rbにindexアクションを追加し、 app/view/index.html.erbを作成してみたのですが、 ActionController::UnknownFormat in HogesController#index HogesController#index is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: [] NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot. は解消されませんでした。
退会済みユーザー

退会済みユーザー

2017/11/02 07:59

formatがないと言ってるので、htmlじゃなくてhtmとか書いてるとか、色々ありそうですが、とりあえず原因が判らないので、rails g scaffoldで新しく作ってみてください。そこに書いていきましょう~
zendendo

2017/11/02 12:01

すいません。 確認してみたら、viewのフォルダ名がhoge(単数形)になっていました。 フォルダ名をhoges(app/views/hoges)にしたら、 ActionController::UnknownFormat in HogesController#index は解消されました。 入力画面が表示され、メールとパスワードを入力し登録ボタンを押したのですが、今度は NoMethodError in HogesController#create undefined method `build_default_account' for #<User:0x007f7c68d4f440> Did you mean? build_account というエラーが出てしまいました。
退会済みユーザー

退会済みユーザー

2017/11/03 01:22 編集

記述ありがとうございます。拝見しました。 まずは、PWとEmailがDBに登録できるか確認しましょう。 Create側には以下の内容だけを書いてまずは試してみましょう。 controller側には @user = User.new(user_params) @user.save の内容だけで大丈夫です。
退会済みユーザー

退会済みユーザー

2017/11/03 02:01

undefined method `build_default_account` そんなメソッドは存在していないって言ってますね。 どこかスペルミスをしているようです。確認をお願いいたします。
zendendo

2017/11/03 02:23 編集

2017/11/03 10:22のアドバイスを試す前に、 今一度、今回の質問で作成や変更をしたファイルを確認・再記入して ユーザー登録と実行してみたところ、 うまくいったみたいです! データベースの中身を確認も ユーザーテーブルにはメールアドレスとパスワードが、 アカウントテーブルには口座番号とuser_idと残高が 作成されていました! ここまで助けて下さりありがとうございました!
退会済みユーザー

退会済みユーザー

2017/11/03 04:57

はーい。良かったです。 今回使った機能はアソシエーションというものです。 https://qiita.com/To_BB/items/47d2c7b1bc3513025d7b https://qiita.com/seimiyajun/items/cd398f741ac108cf11f8 また、View側でリレーションを使う方法や、has_manyにした時も 記述が変わってきます。 まずは書籍で何ができるのかを把握することもいいかもです。 https://www.amazon.co.jp/Ruby-Rails-5アプリケーションプログラミング-山田-祥寛/dp/4774188832/ref=sr_1_1?ie=UTF8&qid=1509684888&sr=8-1&keywords=ruby+on+rails RoRは初心者向けではないので、大変かと思いますが頑張ってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問