2016-06-11 9 views
0

Ich verwende ein Formular, um Daten für zwei Modelle einzugeben. Wenn ich das Elternmodell (Mieter) speichere, wird auch das Kindmodell (Benutzer) gespeichert, aber nur, wenn ich die Benutzer-ID im Benutzermodell nicht validiere. Wenn ich validates :tenant_id, presence: true im Benutzermodell mache, wird der Validierungsfehler "Benutzermandant darf nicht leer sein" angezeigt. Irgendwelche Ideen warum?Die Validierung funktioniert nicht wie erwartet für verwandte Modelle in Rails 4?

Tenant-Modell:

class Tenant < ActiveRecord::Base 

    has_many :users, dependent: :destroy, inverse_of: :tenant 
    accepts_nested_attributes_for :users  

    before_validation do 
    self.status = 0 
    self.name = name_orig.upcase 
    email.downcase! 
    end 

    validates :name_orig, presence: true, length: { maximum: 255 } 

    validates :name, uniqueness: { case_sensitive: false } 

    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i 
    validates :email, presence: true, length: { maximum: 255 }, 
        format: { with: VALID_EMAIL_REGEX }, 
        uniqueness: { case_sensitive: false } 

    validates :status, presence: true 

end 

User-Modell:

class User < ActiveRecord::Base 

    belongs_to :tenant, inverse_of: :users 
    validates_presence_of :tenant 

    before_validation do 
    self.status = 0 
    self.email = email.downcase 
    end 

    VALID_USERNAME_REGEX = /\A\w+\s?\w*\z/i 
    validates :name, presence: true, length: { maximum: 50 }, 
        format: { with: VALID_USERNAME_REGEX }, 
        uniqueness: { case_sensitive: false } 

    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i 
    validates :email, presence: true, length: { maximum: 255 }, 
        format: { with: VALID_EMAIL_REGEX }, 
        uniqueness: { case_sensitive: false } 

    has_secure_password 
    validates :password, presence: true, length: { minimum: 6 } 

    validates :tenant_id, presence: true 

    validates :status, presence: true 

end 

Tenant-Controller:

class TenantsController < ApplicationController 

    def new 
    @tenant = Tenant.new 
    @tenant.users.build 
    end 

    def create   
    @tenant = Tenant.new(tenant_params) 
    @tenant.save 

    if @tenant.save 
     flash[:success] = "Welcome!" 
     redirect_to @tenant # redirects to tenant profile 
    else 
     render 'new' 
    end 
    end 


    private 

    def tenant_params 
     params.require(:tenant).permit(:name_orig, :email, 
      users_attributes: [:name, :email, :password, :password_confirmation]) 
    end 

end 

Anmelden Form:

<%= form_for(@tenant) do |f| %> 

    <%= render 'shared/tenant_error_messages' %> 

    <%= f.label :name_orig, "Company name" %> 
    <%= f.text_field :name_orig, class: 'form-control' %> 

    <%= f.label :email, "Company e-mail" %> 
    <%= f.email_field :email, class: 'form-control' %> 

    <%= f.fields_for(:users) do |u| %> 

    <%= u.label :name, "User name" %> 
    <%= u.text_field :name, class: 'form-control' %> 

    <%= u.label :email, "User e-mail" %> 
    <%= u.email_field :email, class: 'form-control' %> 

    <%= u.label :password, "Password" %> 
    <%= u.password_field :password, class: 'form-control' %> 

    <%= u.label :password_confirmation, "Password confirmation" %> 
    <%= u.password_field :password_confirmation, class: 'form-control' %> 

    <% end %> 

    <%= f.submit "Save", class: "btn btn-primary" %> 
<% end %> 
+0

Bitte aktualisieren Sie Ihre Frage mit dem Formularcode. – Pavan

+0

Warum möchten Sie Daten für zwei Modelle gleichzeitig eingeben? (Sie brauchen nicht validates: tenant_id, present: true, da Sie bereits validides_presence_of: tenant haben) –

+0

@Pavan, Ich habe das Anmeldeformular – Dmitri

Antwort

0

Da Sie verschachtelte Attribute verwenden und beide Modelle gleichzeitig speichern, können Sie tenant_id für user nicht validieren, da sie in einer Transaktion beibehalten werden.

Da tenant nicht beibehalten wird, hat es noch keine ID. Da es keine ID hat, kann tenant_id für user nicht sein.

In diesem Fall tenant_id Validierung ist sinnlos, da Sie kein user ohne tenant seit user wird gebaut oben auf tenant bestehen kann. Wenn Ihr Benutzer also dauerhaft bleibt, wird auch ein entsprechender Mieter anwesend sein.

Im Fall, dass Sie erwähnt, wo die Nutzer auf einer unabhängigen Form anmelden können -

Um zu überprüfen, dass ein Mieter in der Aktions Verwendung schaffen in Verbindung gebracht werden:

tenant = Tenant.find_by(params[:tenant_id]) 
user = tenant.users.build(user_params) 

statt

user = User.new(user_params)

Auf diese Weise werden Sie keine Waisenkinder haben

+0

Danke @Kkulikovskis! – Dmitri

Verwandte Themen