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.

Reply via email to