🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails 5

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

Q&A

解決済

2回答

1011閲覧

create アクションが動かない (2段階の登録)

lucky_luci

総合スコア18

Ruby on Rails 5

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

0グッド

0クリップ

投稿2019/10/09 12:34

編集2019/10/11 11:22

user情報登録後、info情報登録という画面遷移にしたい。
infoでのcreateアクション(登録)がうまくいきません

*ご回答を受けて修正しました。
前提>>
deviseを入れています。
registratin/new.html(user model)でuser情報を登録、→登録したらinfo.new.html.erb(info model)でinfo情報の登録→登録完了という流れを想定

registration/newのcontrollerとしてusers/registration_controller.rbを作成
infoのcontrollerとしてinfos_controller.rebを作成

現象>>
info/new.html.erbで登録ボタンを押してもページがリロードされる(登録されない)
ターミナルでinfo.saveができない(トランザクションが取り消される)

irb(main):001:0> info= Info.new({tel_number: 00}) => #<Info id: nil, age: nil, sex: nil, tel_number: "0", face_picture: nil, hitokoto_shoukai: nil, shoukaibun: nil, user_id: nil, created_at: nil, updated_at: nil> irb(main):002:0> info.save (0.3ms) BEGIN (1.0ms) ROLLBACK => false

user情報(user table)
schema.rb

create_table "users", force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" t.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "username" t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end

info情報(info table)

create_table "infos", force: :cascade do |t| t.integer "age" t.string "sex" t.string "tel_number" t.bigint "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["user_id"], name: "index_infos_on_user_id" end

user.rb(user model)

class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable # ,:trackable has_many :infos, dependent: :destroy end

info.rb(info model)

class Info < ApplicationRecord belongs_to :user end

routes.rb

Rails.application.routes.draw do devise_for :users, controllers: { :registrations => 'users/registrations', :sessions => 'users/sessions' } resources :users, :only => [:index, :show] root "users#index" resources :messages, :only => [:create] resources :rooms, :only => [:create, :show, :index] devise_scope :user do get "sign_in", :to => "users/sessions#new" get "sign_out", :to => "users/sessions#destroy" end get '/infos/new' => 'infos#new' post '/infos/new' => 'infos#create' get '/infos/:id/edit' => 'infos#edit' end

infos_controller.rb

class IinfosController < ApplicationController def new #修正 @user=User.find(params[:id]) @info=Info.new(params.require(:info).permit(:age, :sex, :tel_number,:face_picture, :user_id)) end def create #修正 @info=Info.new(params.require(:info).permit(:age, :sex, :tel_number,:face_picture, :user_id)) @info.save if @info.save redirect_to users_path else redirect_to info_new_path end end end

users/registration_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController # The path used after sign up. class Users::RegistrationsController < Devise::RegistrationsController # The path used after sign up. def after_sign_up_path_for(resource) super(resource) infos_new_path(@user.id) #修正 end end end

view>>
devise/registrations.new.html/erb

<%= 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 :Please_enter_your_Name, :class => "myinfo-label" %> <%= f.text_field :username, autofocus: true, :class =>"myinfo_basic", :placeholder =>'Name' %> </div> <div class="field"> <%= f.label :Please_enter_your_Email, :class => "myinfo-label" %> <%= f.email_field :email, autofocus: true, autocomplete: "email", :class =>"myinfo_basic", :placeholder =>'Email' %> </div> <div class="field"> <%= f.label :Please_enter_your_Password, :class => "myinfo-label" %> <% if @minimum_password_length %> <em style ="color: #a4b3ef">(<%= @minimum_password_length %> characters minimum)</em> <% end %><br /> <%= f.password_field :password, autocomplete: "new-password", :class =>"myinfo_basic", :placeholder => 'Password' %> </div> <div class="field"> <%= f.label :Please_enter_your_Password_again, :class => "myinfo-label" %> <%= f.password_field :password_confirmation, autocomplete: "new-password", :class =>"myinfo_basic", :placeholder => 'Password again' %> </div> <div class="actions"> <%= f.submit "SIGNUP",:class => "regi-btn" %> </div> <% end %>

view>>
infos/new.html.erb

<%= form_with url: infos_new_path, local: true do |f| %> class="fas fa-cog fa-fw"></i> BASIC INFO</u></h3> <div class ="myinfo-label">Please enter your Phone Number</div> <%= f.text_field :tel_number, :class => "myinfo_basic", :placeholder => 'Tel Number', :maxlength =>"15" %> <div class ="myinfo-label">Please enter your Age</div> <%= f.text_field :age, :class => "myinfo_basic_age", :placeholder => "Age", :maxlength =>"3" %> <div class ="myinfo-label">Please choice your Sex</div> <%= f.radio_button :sex, "男" , :class=> "radio_btn", :id => "rlabel1" %> <%= f.label ' Men', :for => "rlabel1" %> <%= f.radio_button :sex, "女", :class=> "radio_btn", :id => "rlabel2" %> <%= f.label ' Women', :for => "rlabel2" %> <%= f.radio_button :sex, "その他", :class=> "radio_btn", :id => "rlabel3" %> <%= f.label ' Others', :for => "rlabel3" %> <%= f.submit 'REGIST as a GEST', :id => 'regi-btn-guest' %>

user登録時のidをinfo登録時に受けわたすというコードも書かねばならぬと思いますが、やり方がわかりません。

合わせてご教授頂けますと幸いです。

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

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

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

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

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

guest

回答2

0

registratin/new.html(user model)でuser情報を登録、→登録したらinfo.new.html.erb(info model)でinfo情報の登録→登録完了という流れを想定

ターミナルでinfo.saveができない(トランザクションが取り消される)

Userモデルにhas_oneでInfoを紐づかせ、登録したユーザー情報を取り出して

rb

1@info = user.build_info

とするのがRailsらしいやり方です。

info/new.html.erbで登録ボタンを押してもページがリロードされる(登録されない)

リロードではなく、画面遷移していないだけではないですか?

erb

1<%= form_with url: infos_new_path, local: true do |f| %>

フォーム送信を非同期処理しない場合は、このようにlocal: trueが必要です。

投稿2019/10/10 00:19

Mugheart

総合スコア2349

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

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

lucky_luci

2019/10/14 02:44

ありがとうございます。おっしゃる通り、リロードではなく、遷移していないだけでした。 <%= form_with(model: @info, url: infos_path, local: true )do |f| %>でいけました。 @info = user.build_infoはcontrollerへの記述でしょうか。
Mugheart

2019/10/14 04:01

はい、コントローラへの記述です
guest

0

ベストアンサー

rails console でsaveできないのは、user_id に値が入っていないためです。
belongs_to :user となっているので、railsがそういうvalidationを定義しています。
info.save に失敗した後、info.errors.messages してみたら直ぐ判ったと思います。
info_controllerのcreateでも価なしにsaveしているので同じ原因です。
@info=Info.new ではなく
@info=Info.new(params.require(:info).permit(必要なカラムの列挙)
にしてください。

あ、new.htmlからuser_idが渡ってきませんね。hidden_field で :user_id を入れておいて下さい。

投稿2019/10/09 14:16

編集2019/10/09 14:18
winterboum

総合スコア23567

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

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

lucky_luci

2019/10/11 11:26

ありがとうございます。registrtion_controllerにidを受け渡すコードを書き、(上記コードブロックご参照ください info_new_path → infos_new_path(@user.id))、info_cintrollerを修正(@info=Info.new→@info=Info.new(params.require(:info).permit(必要なカラムの列挙)、def newにuser=User.find(params[:id])、をしたのですが、Couldn't find User without an IDエラーが出てしまい、info.new画面が表示されないというエラーが出てしまいました。urlはhttp://localhost:3000/infos/new.12となっており、「.」が気になりますがidが渡せてるようなのですが。。 リンク側とcontroller側でidの設定していると思いますが、もしよろしければご教示くださいませ。
winterboum

2019/10/11 11:49

回答するとき全体を眺めずに、「ROLLBACK」の問題だけ見てたので気が付かなかったのですが、全体をみると色々おかしな、というか標準と違う所があり、はて、、、という。 新規登録の form の所に infos_new_path というのが?? railsの通常は new は 新規登録画面を表示するための PATHです。 そこから新規登録へのPATHは create です。 が、 infos_create_path だと標準ではないので、戸惑い(とか勘違いとか)を引き起こします。 routs.rb で resources :infos としなかったのはなにか理由がありますか? その方が他の人に見てもらう時に混乱しません。 あと、user_idの渡し方は*_path のパラメータに入れるのではなく、f.hidden_fieldが良いです。 もっと良いのは Mugheatさんの回答の方法
lucky_luci

2019/10/14 02:42

御回答ありがとうございます。new.html.erbに <%= form_with(model: @info, url: infos_path, local: true )do |f| %> <%= f.hidden_field :user_id, :value => current_user.id %>でいけました。 resourcesにしなかったのは理由は特にありませんので、resourcesにいたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問