1

本当にRails 5はRails 4とは異なるニュアンスを持っています。私が行っていることは、フォームにはエラーがリロードされます。プロファイルユーザーは存在する必要がありますプロファイルユーザーは空白にすることはできません。私は他のを持っていたしているRails 5 - ネストされたモデルの親モデルが子モデルの前に保存されていないためロールバックされます

Puma starting in single mode... 
* Version 3.7.0 (ruby 2.2.6-p396), codename: Snowy Sagebrush 
* Min threads: 5, max threads: 5 
* Environment: development 
* Listening on tcp://0.0.0.0:3000 
Use Ctrl-C to stop 
Started POST "/users" for 192.168.0.31 at 2017-03-09 18:51:04 -0500 
Cannot render console from 192.168.0.31! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 
    ActiveRecord::SchemaMigration Load (0.2ms) SELECT `schema_migrations`.* FROM `schema_migrations` 
Processing by UsersController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"JPKO+ppAYqwWS8tWeXhEtbUWynXREu9jYlF0KIlyPgUaabHSzjPZocSxCvr/WEm1r6wAQyT1CvA6hNkZWfPD3Q==", "user"=>{"username"=>"test", "password"=>"[FILTERED]", "user_type_id"=>"1", "profile_attributes"=>{"first_name"=>"123", "middle_name"=>"123", "last_name"=>"123", "email"=>"[email protected]", "phone_number"=>"1234567890", "cell_number"=>"1234567890"}}, "commit"=>"Create User"} 
    (0.1ms) BEGIN 
    (0.2ms) ROLLBACK 
    Rendering users/new.html.erb within layouts/application 
    Rendered users/_form.html.erb (112.5ms) 
    Rendered users/new.html.erb within layouts/application (118.7ms) 
Completed 200 OK in 834ms (Views: 780.1ms | ActiveRecord: 2.2ms) 

:フォームの負荷は罰金が、今までコンソールに次の出力で子モデルを保存しようとする前に、親モデルを保存するために失敗している理由何のために、ネストされたモデルのフォームを含みますこの関係から問題が発生し、私はプロジェクトを再構築する必要があると考えています。 ここでは、この問題の周りに関連するコードのすべてです:私は同様の問題を抱えていた

############################################################################### 
### Users Model 
############################################################################### 
    class User < ApplicationRecord 
     has_one :profile, inverse_of: :user 
     accepts_nested_attributes_for :profile, allow_destroy: true 
    end 

############################################################################### 
### Profile Model 
############################################################################### 
    class Profile < ApplicationRecord 
     belongs_to :user, inverse_of: :profile 
     validates_presence_of :user 
    end 
############################################################################### 
### Users Controller 
############################################################################### 
    class UsersController < ApplicationController 
     before_action :set_user, only: [:show, :edit, :update, :destroy] 

     # GET /users 
     # GET /users.json 
     def index 
     @users = User.all 
     end 

     # GET /users/1 
     # GET /users/1.json 
     def show 
     @user.build_profile 
     end 

     # GET /users/new 
     def new 
     @user = User.new 
     @user.build_profile 
     end 

     # GET /users/1/edit 
     def edit 
     @user.build_profile 
     end 

     # POST /users 
     # POST /users.json 
     def create 
     @user = User.new(user_params) 

     respond_to do |format| 
      if @user.save 
      format.html { redirect_to @user, notice: 'User was successfully created.' } 
      format.json { render :show, status: :created, location: @user } 
      else 
      format.html { render :new } 
      format.json { render json: @user.errors, status: :unprocessable_entity } 
      end 
     end 
     end 

     # PATCH/PUT /users/1 
     # PATCH/PUT /users/1.json 
     def update 
     respond_to do |format| 
      if @user.update(user_params) 
      format.html { redirect_to @user, notice: 'User was successfully updated.' } 
      format.json { render :show, status: :ok, location: @user } 
      else 
      format.html { render :edit } 
      format.json { render json: @user.errors, status: :unprocessable_entity } 
      end 
     end 
     end 

     # DELETE /users/1 
     # DELETE /users/1.json 
     def destroy 
     @user.destroy 
     respond_to do |format| 
      format.html { redirect_to users_url, notice: 'User was successfully destroyed.' } 
      format.json { head :no_content } 
     end 
     end 

     private 
     # Use callbacks to share common setup or constraints between actions. 
     def set_user 
      @user = User.find(params[:id]) 
     end 

     # Never trust parameters from the scary internet, only allow the white list through. 
     def user_params 
      params.require(:user).permit(:username, :password, :user_type_id, profile_attributes: [:id, :user_id, :first_name, :middle_name, :last_name, :phone_number, :cell_number, :email]) 
     end 
    end 

############################################################################### 
### Form View 
############################################################################### 
    <%= form_for(@user) do |f| %> 
     <% if user.errors.any? %> 
     <div id="error_explanation"> 
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2> 

      <ul> 
      <% user.errors.full_messages.each do |message| %> 
      <li><%= message %></li> 
      <% end %> 
      <!--<li><%= debug f %></li>--> 
      </ul> 
     </div> 
     <% end %> 

     <div class="field"> 
     <%= f.label :username %> 
     <%= f.text_field :username %> 
     </div> 

     <div class="field"> 
     <%= f.label :password %> 
     <%= f.text_field :password %> 
     </div> 

     <div class="field"> 
     <% if params[:trainer] == "true" %> 
      <%= f.label :user_type_id %> 
      <%= f.text_field :user_type_id, :readonly => true, :value => '2' %> 
     <% else %> 
      <%= f.label :user_type_id %> 
      <%= f.text_field :user_type_id, :readonly => true, :value => '1' %> 
     <% end %> 
     </div> 
     <h2>Account Profile</h2> 
     <%= f.fields_for :profile do |profile| %> 
      <%#= profile.inspect %> 
      <div> 
       <%= profile.label :first_name %> 
       <%= profile.text_field :first_name %> 
      </div> 
      <div> 
       <%= profile.label :middle_name %> 
       <%= profile.text_field :middle_name %> 
      </div> 
      <div> 
       <%= profile.label :last_name %> 
       <%= profile.text_field :last_name %> 
      </div> 
      <div> 
       <%= profile.label :email %> 
       <%= profile.text_field :email %> 
      </div> 
      <div> 
       <%= profile.label :phone_number %> 
       <%= profile.telephone_field :phone_number %> 
      </div> 
      <div> 
       <%= profile.label :cell_phone %> 
       <%= profile.telephone_field :cell_number %> 
      </div> 
     <% end %> 
     <div class="actions"> 
     <%= f.submit %> 
     </div> 
     <%= debug params %> 
     <%= debug user %> 
     <%= debug user.profile %> 
    <% end %> 
+0

解決策がないようですが、誰も助けを提供していないので、私はそれがバグだと仮定しようとしています。私はこのシステムに私に恩恵を与えるでしょう。 –

答えて

1

申し訳ありません他の質問で質問を言い換えましたが、私はついにこの回答を見つけました。だから私はここから質問を出していたのと同じ方法で誰かが問題を探しているので、そこから私の答えを貼り付けています。

私は多くの人々がこれに苦労していることを知っているので、私は自分自身の質問に答えています。私は実際に答えを持っており、ドキュメンテーションへのあいまいな反応ではありません。

まず、この例では1対1の関係を使用します。

  • 自動保存:
  • 真accepts_nested_attributes_for:ここ
  • は真:モデル、allow_destroyあなたがあなたの関係を作成するときは、親モデルは、以下の

    1. inverse_ofを持っていることを確認する必要がありますユーザーがモデル化したら、私は説明します

      class User < ApplicationRecord 
          has_one :profile, inverse_of: :user, autosave: true 
          accepts_nested_attributes_for :profile, allow_destroy: true 
      end 
      

      Rails 5ではinverse_ofが必要です:これは外部キーを介して関係があり、フォームデータを保存するときにネストされたモデルに設定する必要があることをRailsに通知するためです。 の自動保存を残す場合は、を関係線からオフにして、user_idはプロファイルテーブルとその他の列に保存しません。ただし、検証をオフにしてからエラーが発生しない限りuser_idなしで保存します。ここで起こっているのはの自動保存です:trueは、のプロファイルモデルのネストされた属性に格納するために、ユーザレコードが最初に保存されるようにしています。user_id それは一言で言えば、なぜuser_idが子供に行き渡っていなかったのですか?それはコミットするのではなくロールバックしていました。 また最後に1つの問題があります。あなたのコントローラにあなたが追加する必要のある編集ルートを教えてくれる投稿があります。@ user.build_profile私の投稿にあるようです。コンソール出力を評価した後、それはあなたが、それは最初からプロファイルを再構築し、現在のユーザーに一致するレコードのnullにUSER_IDをリセットして見れば、あなたは

      Started GET "https://stackoverflow.com/users/1/edit" for 192.168.0.31 at 2017-03-12 22:38:17 -0400 
      Cannot render console from 192.168.0.31! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 
      Processing by UsersController#edit as HTML 
          Parameters: {"id"=>"1"} 
          User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 
          Profile Load (0.5ms) SELECT `profiles`.* FROM `profiles` WHERE `profiles`.`user_id` = 1 LIMIT 1 
          (0.1ms) BEGIN 
          SQL (0.5ms) UPDATE `profiles` SET `user_id` = NULL, `updated_at` = '2017-03-13 02:38:17' WHERE `profiles`.`id` = 1 
          (59.5ms) COMMIT 
          Rendering users/edit.html.erb within layouts/application 
          Rendered users/_form.html.erb (44.8ms) 
          Rendered users/edit.html.erb within layouts/application (50.2ms) 
      Completed 200 OK in 174ms (Views: 98.6ms | ActiveRecord: 61.1ms) 
      

      になり、彼らはDEAD間違っているそれをしないでください編集。だから私はこの提案をしているたくさんの投稿を見てきたので、これを非常に注意してください。

    0

    (ネストされた属性に保存されませんでした)。

    コントローラーで@user.build_profile@user.profile.build(params[:profile])に変更し、問題を解決しました。

    +0

    私はすぐに、意味がある方法でそれを試みます。もし私が尋ねることができるなら、あなたはこれをどのように理解しましたか私は数日間グーグルで遊んでいた! –

    +0

    いいえ、結果は**初期化されていない定数です。User :: Profile ** –

    +0

    申し訳ありませんが、型がありました。 '@ user.profile.build(params [:profile])'の代わりに '@ user.profiles.build(params [:profile])'を使うことができます。 は、私はそれが ''持ってhas_one' <==> 'belongs_to'関係の場合には、必ずしもではないことを知っているhttp://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html からそれを手に入れました。これは、テーブル間の 'has_many' <==>' belongs_to'結合の典型であるため、すべてのユーザのプロファイルを返します(それはちょうどhas_oneです)。 – bencekiss

    関連する問題