Reputation: 2978
I have User
and Email
tables, with relation one User
has one Email
(as a login in a system). But user may has many Emails
as own contacts.
class User < ApplicationRecord
has_secure_password
has_one :email
# has_many :phones, as: :contactable
accepts_nested_attributes_for :email
end
class Email < ApplicationRecord
belongs_to :contactable, polymorphic: true
accepts_nested_attributes_for :contactable
validates :email, presence: true, uniqueness: true
end
and user_controller.rb
def create
@user = User.new(user_params)
if @user.save
render json: @user, except: :password_digest, status: :created, location: @user
else
render json: @user.errors, status: :unprocessable_entity
end
end
private
def user_params
params.permit(
:email,
:password,
:first_name,
:last_name,
:patronymic,
email_attributes: [:email]
)
end
when I try send requests like this
{
"email": "[email protected]",
"phone": "+799999999999",
"password": "test",
"first_name": "First-name",
"last_name": "Last-name",
"patronymic": "Patronymic"
}
I have this error
"exception": "#<ActiveRecord::AssociationTypeMismatch: Email(#70266002240460) expected, got \"[email protected]\" which is an instance of String(#47039052873240)>"
what I doing wrong?
UPDATE
has_one
relation by belongs_to
and changed user_params
function to this
params.permit(:password, :first_name, :last_name, :patronymic, email_attributes: [:email])
but if I try to make a post request like this:
{
"email_attributes": {
"email": "[email protected]"
},
"phone": "+799999999999",
"password": "test",
"first_name": "First-name",
"last_name": "Last-name",
"patronymic": "Patronymic"
}
I have error
{
"email.contactable": [
"must exist"
]
}
And sub-question: how to get rid of email_attributes?
Upvotes: 0
Views: 649
Reputation: 27747
Your user doesn't have a column called email, it has an association that is meant to be a new email object, with its own attributes.
If it were just a column, then you could have params come in something like:
user: {
name: 'Fred', # this is a column on users
email: '[email protected]' # this is another column on users
}
But instead, you need it to act like a separate model. Now your email model is a database table on its own, and has a column, eg called 'email' right? If so, then you'd need the params to come in something ike this:
user: {
name: 'Fred', # this is a column on users
email: { # this tells us that it's another object called 'email'
email: '[email protected]' # this is a column on emails
}
}
Obviously you'd need to rename columns to match your own.
I'll also point out that in your permit, you have both an email as a column on users and also as email_attributes
- which says the attributes of a different, associated model called email
Upvotes: 1