# Create several models at once and validating

**URL:** <https://www.ruby-forum.com/t/create-several-models-at-once-and-validating/65133>\
**Category:** Rails\
**Created:** [August 16, 2006, 1:46pm UTC](https://www.ruby-forum.com/t/create-several-models-at-once-and-validating/65133 "2006-08-16T13:46:02Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![eyp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e274bd/32.png) [@eyp](https://www.ruby-forum.com/u/eyp)\
**Post date:** [August 16, 2006, 1:46pm UTC](https://www.ruby-forum.com/t/create-several-models-at-once-and-validating/65133/1 "2006-08-16T13:46:02Z")

</div>

I have two models User and Team. Also I have a register form where the  
new  
user fill in her data and choose a name for a Team.

Well, in the user model there are several validations which work fine,  
but  
team model also have a validation for a uniqueness name that doesn’t  
fire up  
when she gives an existent team’s name.

This is the flow it follows:

/user/new -\> it shows a form to fill user’s data and a team’s name -\>  
Create -\>  
UserController  
def create  
@user = User.create(params)  
if request.post? and @user.save  
…  
end  
end

User  
validates\_uniqueness\_of :username \<— THIS WORKS FINE  
def self.create  
user = User.new(params[:user])  
team = Team.new(params[:team])  
user.team = team  
user  
end

Team  
validates\_uniqueness\_of :name \<— THIS DOESN’T WORK

What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![eyp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e274bd/32.png) [@eyp](https://www.ruby-forum.com/u/eyp)\
**Post date:** [August 17, 2006, 12:25am UTC](https://www.ruby-forum.com/t/create-several-models-at-once-and-validating/65133/2 "2006-08-17T00:25:10Z")

</div>

> User  
> validates\_uniqueness\_of :username \<— THIS WORKS FINE  
> def self.create  
> user = User.new(params[:user])  
> team = Team.new(params[:team])  
> user.team = team  
> user  
> end

This is bad. Your model should not be dependent on the View or the  
Controller - by using the params hash in your model code, you are  
restricting your model to only work in a request context. This  
prevents you from using User.create anywhere but from a controller  
that is called from a form that has a :users parameter set. You are  
also changing the semantics of the create method, which by convention  
performs a save of the model.  
You should also be wrapping the two save operations in a transaction.

Should be rewritten as:

class UserController  
def create  
@user = User.new(params[:user])  
@team = Team.new(params[:team])  
User.transaction do  
success = @user.save  
success &= @team.save  
if success  
flash[:notice] = ‘User was successfully created.’  
redirect\_to :action =\> ‘list’  
else  
render :action =\> ‘new’  
end  
end  
end  
…

The “success” stuff is there so that both models get a chance to  
validate themselves (which happens on save).

In your view, you will need to also add error output for the @team  
model instance. By default, the scaffolding assumes that there is a  
single model object for a controller and view:

\<%= error\_messages\_for ‘team’ %\>  
\<%= error\_messages\_for ‘user’ %\>

Max

---

<div class="post-metadata">

**Author:** ![eyp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e274bd/32.png) [@eyp](https://www.ruby-forum.com/u/eyp)\
**Post date:** [August 17, 2006, 9:06am UTC](https://www.ruby-forum.com/t/create-several-models-at-once-and-validating/65133/3 "2006-08-17T09:06:32Z")

</div>

> This is bad. Your model should not be dependent on the View or the  
> Controller - by using the params hash in your model code, you are  
> restricting your model to only work in a request context.

Yes, you’re absolutely right, I’ve already change it.

> class UserController  
> def create  
> @user = User.new(params[:user])  
> @team = Team.new(params[:team])  
> User.transaction do  
> success = @user.save  
> success &= @team.save  
> if success  
> flash[:notice] = ‘User was successfully created.’  
> redirect\_to :action =\> ‘list’  
> else  
> render :action =\> ‘new’  
> end  
> end  
> end

But I don’t want this behaviour. I forgot to mention that User and Team  
are related:

User Team  
has\_one :team \<--------------\> belongs\_to :user

Thus I did @user.team = @team then @user.save that saves my user and the  
related team too.

But if I do @user.save and then @team.save, whether validations on team  
failed,  
the user is created but team doesn’t and I want non of them to be saved.

---

<div class="post-metadata">

**Author:** ![eyp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e274bd/32.png) [@eyp](https://www.ruby-forum.com/u/eyp)\
**Post date:** [August 17, 2006, 9:36am UTC](https://www.ruby-forum.com/t/create-several-models-at-once-and-validating/65133/4 "2006-08-17T09:36:46Z")

</div>

kris wrote:

> You can ensure that the models are both valid, e.g. with .valid? first.

Thanks, that’s the way I resolved it, just now I was going to post it.

---

<div class="post-metadata">

**Author:** ![eyp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e274bd/32.png) [@eyp](https://www.ruby-forum.com/u/eyp)\
**Post date:** [August 17, 2006, 9:35am UTC](https://www.ruby-forum.com/t/create-several-models-at-once-and-validating/65133/5 "2006-08-17T09:35:09Z")

</div>

You can ensure that the models are both valid, e.g. with .valid? first.
