Create several models at once and validating

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?

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

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.

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.

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