Validation doesn't work as expected for related models in Rails 4? -
i use 1 form enter data 2 models. when save parent model (tenant) child model (user) gets saved, if don't validate tenant_id in user model. if validates :tenant_id, presence: true
in user model validation error "users tenant can't blank" displayed. ideas why?
tenant model:
class tenant < activerecord::base has_many :users, dependent: :destroy, inverse_of: :tenant accepts_nested_attributes_for :users before_validation 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+\-.]+@[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 model:
class user < activerecord::base belongs_to :tenant, inverse_of: :users validates_presence_of :tenant before_validation 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+\-.]+@[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 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
signup form:
<%= form_for(@tenant) |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) |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 %>
since using nested attributes , saving both models @ same time, cannot validate tenant_id
user
since persisted in transaction.
because tenant
not persisted, not yet have id. since not have id, there cannot tenant_id
user
.
in case validating tenant_id
pointless, because cannot persist user
without tenant
since user
being built on top of tenant
. if user persisted, corresponding tenant present.
in case mentioned, users can sign on independent form -
to validate tenant associated in create action use:
tenant = tenant.find_by(params[:tenant_id]) user = tenant.users.build(user_params)
instead of
user = user.new(user_params)
this way not have orphan children
Comments
Post a Comment