I am having a weird problem class Post has_many :uploads end class Upload belongs_to :post end In the form in my view the user can upload multiple files at once. In my model there are multiple validations for an Upload, such as being under a certain filesize or not having absurd dimensions if it''s an image, etc. The problem is that if one of the uploads fails validation, the Post object fails validation as well. Previously, I thought I had to specify validates_associated :uploads in the Post model to get this behavior, but seems like that is not the case. If one of the uploads fails I get the error message "Uploads is invalid" in the Post object''s errors, which prevents the Post and all other Uploads from saving whether or not they are valid; so basically one bad upload ruins the whole thing. This is kind of bad since it can take a user a while to upload multiple files, and I think it''s silly to say "one upload out of ten failed, start all over" when some of the uploads might be good. What I would -like- to do is accept as many uploads as possible, having the Post object fail to save only if zero uploads were valid. Any invalid uploads get thrown away (although ideally I could somehow keep their errors stored somewhere [in the Post object?] so I can show the user what uploads failed and why). -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Bumping this before it fades into obscurity forever. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
R. Elliott Mason wrote:> I am having a weird problem > > class Post > has_many :uploads > end > > class Upload > belongs_to :post > end > > In the form in my view the user can upload multiple files at once. In > my model > there are multiple validations for an Upload, such as being under a > certain filesize or not having absurd dimensions if it''s an image, etc. > > The problem is that if one of the uploads fails validation, the Post > object fails validation as well. Previously, I thought I had to specify > validates_associated :uploads in the Post model to get this behavior, > but seems like that is not the case. If one of the uploads fails I get > the error message "Uploads is invalid" in the Post object''s errors, > which prevents the Post and all other Uploads from saving whether or not > they are valid; so basically one bad upload ruins the whole thing. This > is kind of bad since it can take a user a while to upload multiple > files, and I think it''s silly to say "one upload out of ten failed, > start all over" when some of the uploads might be good. > > What I would -like- to do is accept as many uploads as possible, having > the Post object fail to save only if zero uploads were valid. Any > invalid uploads get thrown away (although ideally I could somehow keep > their errors stored somewhere [in the Post object?] so I can show the > user what uploads failed and why).The file_column plugin, and perhaps other file upload plugins, will automatically store the valid uploads in temporary files so that they do not have to be uploaded again when the form is re-presented. But if you want the partial save to proceed you''ll have to loop through the upload params, creating upload objects, calling valid? on them, and adding them to the post''s uploads collection if valid and to a reject array if not, then saving the post (along with the valid uploads) if at least one upload is valid. Re-present the invalid uploads to the user. If you still need to get rid of the automatic associate validity check that is causing your "Uploads is invalid" message, just add: class Post validate_associated_records_for_uploads() end end -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Had no idea such a method would exist. Thanks, I''ll try it out. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hm, the problem I''m finding in this approach is that validation is being called twice; once when I call valid? for the object and a second time before the Post is saved. This wouldn''t be too much of an issue if my validations didn''t require database queries to be run, but unfortunately because they are run it causes an unnecessary about of redundancy. I would use file_column but I think I might be too far along in development for that. Maybe I should just try to mimic how it saves files temporarily before re-presenting the form. I just figured if a user makes an invalid upload, the upload is probably going to stay invalid. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
R. Elliott Mason wrote:> Hm, the problem I''m finding in this approach is that validation is being > called twice; once when I call valid? for the object and a second time > before the Post is saved. This wouldn''t be too much of an issue if my > validations didn''t require database queries to be run, but unfortunately > because they are run it causes an unnecessary about of redundancy.save(false) saves without validation; and the automatic validation of has_many associates can be turned off in the way described in my last post. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
It seems like the uploads, associated with the post, are being validated as the post is saved. Both the post and its associated objects having not been saved, all the objects go through their validations, which makes sense I guess. Overriding the validate_associated_records_for_uploads method prevents the validation from being run twice, but as each upload object is saved, it is validated. I tried to instead use your save(false) method and save the uploads -before- I saved the post object, after calling valid? on those objects. I separated the good uploads from the bad and left the bad in the Post object as post.bad_uploads. However, saving the uploads ahead of time didn''t work out well either. Validation was still run as the post object was saved. I could try to save the post and upload completely separate from each other but the problem is their validations are related. A post shouldn''t be saved if its uploads are bad, and an upload shouldn''t be saved if the post is bad, so it''s turning out to be somewhat of a mess. So overriding validate_associated_records_for_uploads() just really prevents validation from being run THREE times in my case (once with that method, once with valid? and a third time when the post is saved.) I guess I can try to use file_column and perhaps modify it to suit my needs. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
R. Elliott Mason wrote:> It seems like the uploads, associated with the post, are being validated > as the post is saved. Both the post and its associated objects having > not been saved, all the objects go through their validations, which > makes sense I guess. Overriding the > validate_associated_records_for_uploads method prevents the validation > from being run twice, but as each upload object is saved, it is > validated. > > I tried to instead use your save(false) method and save the uploads > -before- I saved the post object, after calling valid? on those objects. > I separated the good uploads from the bad and left the bad in the Post > object as post.bad_uploads. However, saving the uploads ahead of time > didn''t work out well either. Validation was still run as the post > object was saved. > > I could try to save the post and upload completely separate from each > other but the problem is their validations are related. A post > shouldn''t be saved if its uploads are bad, and an upload shouldn''t be > saved if the post is bad, so it''s turning out to be somewhat of a mess. > > So overriding validate_associated_records_for_uploads() just really > prevents validation from being run THREE times in my case (once with > that method, once with valid? and a third time when the post is saved.)Yes, Rails 1.2 incorrectly runs validation twice on cascaded saves, even if the parent object is saved with save(false) or save_without_validation. Blocking the validate_associated_records... method gets rid of one, but each new child will still be validated before it''s inserted into the DB. To avoid this you have to do your own save cascade: save the parent using save(false)/save_without_validation without any new children added to its collections. Then separately build and save each child the same way. To save only if everything''s valid you have to first run valid? on each record. if post.valid? && uploads.inject(true) { |v, u| u.valid? && v } post.save(false) uploads.each { |u| u.post = post; u.save(false) } end This can be simplified if post is not a new record. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I seem to have figured it out with your help. I''d post the code but it''s disturbingly tacky, but at least it gets the job done. I don''t think there''s anymore room for elegance with what I have. Maybe I can later figure out how to do the temporary file save for re-presenting the form to the user, but I''m guessing the code behind that isn''t exactly trivial. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---