In that case I'd handle errors like this in the client-side level
besides the database level since I find it simpler, specially if you're
using an OO approach with your models isolated from your views.
In that case, if there is a bug in your client-side code that will send
duplicate entries to the server, in the worst case you'll get a 500
response if you don't handle it in the server.
Another approach if you want to handle this in the server-side would be
to do something like this:
begin
start_database_transaction
company = Company.create! params[:company] # simplified here, just
create the company with minimal params
# then add the partners to the company and ask to validate company.
Now the partners should have a valid company_id and the built-in
validations should work
...
unless company.valid?
handle_validation_error company.errors
raise 'duplicate entries'
end
...
rescue
rollback_database_transaction
end
Of course the suggestion above would only work with serious databases
(ie, not with the MyISAM engine in MySql, which is the default for older
versions of MySql).
In any case I'd suggest to release your gem first and then ask here if
the Rails core would be willing to include it by default in
ActiveRecord. In that case they would be able to look at the
documentation, source code and tests before making a decision.
But I'd like to tell you why I think lots of people are not using nested
params. If they're like me the work-flow would look something like this:
The user clicks in a Add Company button and would be asked the company
name. The application creates the company with no partners associated.
Then the interface would add a button "Add partner" asking for the
partner data. In that case your actions would have to deal with a single
partner at once, making it easier to work with regular validations and
simplifying the logic too.
What I mean is that I find it quite easier to develop applications using
AJAX than trying to create complex forms that do lots of stuff in a
single request. Even testing such forms are painful in my opinion. It is
much easier to split the application in multiple small parts that are
easily testable separately.
Good luck with your decisions,
Rodrigo.
Em 05-08-2012 12:42, Gabriel Sobrinho escreveu:
Rodrigo,
I'm doing that at database level but I'm not handling the exception
because it happens very infrequently.
The point is the validation message that I have to show like any
others validations.
Another problem is that I have more than one case like this per form.
I used the partner case but in this same form I have another nested
called company activities that can't repeat the CNAE (an activity
means initial date, final date and CNAE).
In this form I have 2 "in-memory" validations but I have others that
have more than 5 nested like this.
It will be very painfully if I have to handle each exception to
discover what nested failed and add the error by hand.
Like I said before, I see this problem happening over and over again
in systems I've worked.
But that can be an "enterprise" feature that does not fit to active
record proposal.
In that case, I will keep it as a separated gem.
I just want to be sure if I should submit a PR or something like that :)
On Aug 5, 2012, at 12:26 PM, Rodrigo Rosenfeld Rosas wrote:
That is why constraints should be handled by databases in my opinion.
Just create the unique index in the database and write something like
this:
begin
company.save!
rescue UniqueConstraintException => e # I don't really know the name
for this exception
render json: {error_message: "Please remove the duplicate entries."}
rescue e # general rescuer
log.error "Couldn't create company", e # not sure if that is the
right syntax
render json: {error_message: "We could't process your request.
Please contact our support team."}
end
Well, at least this has always been my opinion and the reason why I
prefer writing validations in the database using unique constraints
or triggers.
Usually the ActiveRecord and Hibernate communities among others don't
recommend this approach if you intend to support multiple databases,
but since I always use PostgreSQL, this is not an issue to me. That
is one of the reasons I prefer Sequel over AR. The Sequel community
will usually prefer handling validations in the database-level even
though you can use validators in Ruby as well to make it easy to
handle simple cases but you should always replicate the validations
in the database level as well.
Well, that is my opinion since you asked :)
Cheers,
Rodrigo.
Em 05-08-2012 11:36, Gabriel Sobrinho escreveu:
Anyone have some opinion?
On Sunday, July 29, 2012 4:17:01 PM UTC-3, Gabriel Sobrinho wrote:
Hi,
Currently uniqueness validator uses database queries which not
work for nested forms.
For example, I have a company form which have many partners and
each partner have a person and a percentage.
Using uniqueness validator, I can not guarantee someone will not
be a partner two times because the partners aren't on database yet.
We've implemented a validator similar to this one:
http://pastie.org/private/osa3pmono5l1ykrd7vipwa
<http://pastie.org/private/osa3pmono5l1ykrd7vipwa>
I'm not sure if the uniqueness validator should handle it.
Take a look: http://pastie.org/private/maxdpn4gmvftzcl2ka0mq
<http://pastie.org/private/maxdpn4gmvftzcl2ka0mq>
I'm not sure if it will be too complex to the proposal of
uniqueness validator but that is a common validation for each
system I've worked in last years.
WDYT? Something like that should be on the active record or a gem?
Cheers,
Gabriel Sobrinho
gabrielsobrinho.com <http://gabrielsobrinho.com/>
--
You received this message because you are subscribed to the Google Groups "Ruby on
Rails: Core" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rubyonrails-core?hl=en.