Ich verwende Rails 5 und alles in seinen neuesten stabilen Versionen. So bekomme ich folgendes:Warum Rails 5 verschachtelte Attribute nicht speichert, weil Elternmodell nicht zuerst speichert
Sie haben Ihre Zuordnung auf erforderlich, aber es fehlt. Verbände werden auf standardmäßig erforderlich in Schienen 5 so, wenn Sie wollen einen leeren Sie optional festlegen müssen halten: auf Ihrem Verband in Modus
Das ist großartig wahr und ich verstehe, was aber vor sich geht Für das Leben von mir kann ich nicht herausfinden, wie das Elternmodell zuerst gespeichert wird, damit die user_id den verschachtelten Modellsatz übersetzt. Ich sehe die gleiche Antwort oben überall, aber niemand erklärt eine andere Arbeit, als den Standard im Initialisierer von "wahr" auf "falsch" zu setzen. DIES LÖST DAS PROBLEM NICHT, da der Datensatz sicher speichert, aber die user_id nicht enthält.
Unten ist, was ich für meine Code-Basis habe, würde ich eher als mit dem oben genannten Zitat zu antworten bitten, könnte mir jemand aufklären, wie das Feld USER_ID in die geschachtelten Attribute während des Speicherns erhalten. Ich weigere mich, die Validierung zu deaktivieren und manuell die Einfügung zu handhaben, da dies nicht der rubinrote Weg ist und von Standards bricht! Vielen Dank im Voraus für jeden, der diese Frage direkt und ohne vage Erklärungen beantworten kann, die von der rubinroten Art der Dinge abweichen!
###Models
#Users
class User < ApplicationRecord
has_one :profile, inverse_of: :user
accepts_nested_attributes_for :profile, allow_destroy: true
end
#Profiles
class Profile < ApplicationRecord
belongs_to :user, inverse_of: :profile
end
###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
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: [:user_id, :first_name, :middle_name, :last_name, :phone_number, :cell_number, :email])
end
end
##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 %>
UPDATE Für den Anfang ich herausgefunden habe, dass Sie automatische Speicherung einschließen müssen: true die Beziehung wie so
class User < ApplicationRecord
has_one :profile, inverse_of: :user, autosave: true
accepts_nested_attributes_for :profile, allow_destroy: true
end
Dann wird der übergeordnete Datensatz wird, bevor das Kind gerettet. Jetzt kommt ein weiterer Gotcha, die ich bin nur nicht sicher und ist ungerade, wenn das Formular abgeschickt wird Sie in der Konsolenausgabe bemerken werde ich unter dem klebte das INSERT INTO profiles
Anweisung enthält die User_id Spalte und den Wert von . Es übergibt die Validierung und sieht so aus, als ob es ordnungsgemäß von der Ausgabe ausgeführt wird. Die Spalte user_id in der Tabelle ist jedoch immer noch null. Ich werde weiter graben, hoffentlich wird einer meiner anderen Rubyies da draußen das sehen und ein paar Ideen haben, wie man das fertigstellen kann. Ich liebe Rails 5 Verbesserungen bisher, aber es wäre nicht ROR ohne kleine interessante Probleme! Nochmals vielen Dank im Voraus!
Started POST "/users" for 192.168.0.31 at 2017-03-12 22:28:14 -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#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"YA7kQnScvlIBy5OiT+BmOQ2bR7J00ANXId38FqNwX37Cejd+6faUyD3rMF4y0qJNKBUYGaxrRZqcLrXonL6ymA==", "user"=>{"username"=>"john", "password"=>"[FILTERED]", "user_type_id"=>"1", "profile_attributes"=>{"first_name"=>"john", "middle_name"=>"r", "last_name"=>"tung", "email"=>"[email protected]", "phone_number"=>"8033207677", "cell_number"=>"8033207677"}}, "commit"=>"Create User"}
(0.1ms) BEGIN
SQL (0.3ms) INSERT INTO `users` (`username`, `password`, `user_type_id`, `created_at`, `updated_at`) VALUES ('john', '0000', 1, '2017-03-13 02:28:14', '2017-03-13 02:28:14')
SQL (0.4ms) INSERT INTO `profiles` (`user_id`, `email`, `first_name`, `middle_name`, `last_name`, `phone_number`, `cell_number`, `created_at`, `updated_at`) VALUES (1, '[email protected]', 'john', 'r', 'tung', '8033207677', '8033207677', '2017-03-13 02:28:14', '2017-03-13 02:28:14')
(10.8ms) COMMIT
Redirected to http://192.168.0.51:3000/users/1
Completed 302 Found in 24ms (ActiveRecord: 11.5ms)
Die 'Autosave'-Option wird ausführlich in den offiziellen Dokumenten von Rails erklärt. http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html – jvnill