2016-06-11 20 views
0

2つのモデルのデータを入力するために1つのフォームを使用します。親モデル(テナント)を保存すると、Userモデルのtenant_idを検証しない場合に限り、子モデル(User)も保存されます。ユーザーモデルでvalidates :tenant_id, presence: trueを実行すると、検証エラー「ユーザーテナントは空白にできません」が表示されます。なぜどんなアイデア?Rails 4の関連モデルで検証が正しく機能しませんか?

テナントモデル:

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 

ユーザモデル:

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 

テナントコントローラ:

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 

登録フォーム:

<%= 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

質問をフォームコードで更新してください。 – Pavan

+0

なぜ2つのモデルのデータを一度に入力したいのですか? (あなたは既に 'validates_presence_of:tenant'を持っているので' validates:tenant_id、presence:true'は必要ありません) –

+0

@Pavan、テナントAの最初のユーザーがサインアップしているときに登録フォーム – Dmitri

答えて

0

ネストされた属性を使用しているため、両方のモデルを同時に保存すると、usertenant_idはトランザクション内で永続化されるため、検証できません。

tenantは永続化されていないため、まだIDはありません。 IDがないため、userの場合はtenant_idにはなりません。 usertenantの上に構築されているので、あなたがtenantなしuserを持続することはできませんのでtenant_idを検証する。この場合

は、無意味です。したがって、ユーザーが継続される場合、対応するテナントも存在します。

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

代わりの

をテナントが作成したアクションの使用に関連付けられますことを確認するには - ユーザーが独立したフォームにサインアップすることができ、あなたが言及した場合、

user = User.new(user_params)

このようにして、孤児はいません。

+0

ありがとう@Kkulikovskis! – Dmitri

関連する問題