I have two problems. I have a comment that has_many uploads. Before
saving the comment, I want to be sure that the upload(s) has passed
validation, but I also need to validate in other ways. For example, I
do not want to save the comment if there is no comment or upload. Or, I
do not want to save the comment if the image has been uploaded
previously (comparing md5s with past upload md5s within the scope of an
IP).
Previously I had all of the upload attributes combined with my Comments
table, which made validation extremely easy. Then when I decided that I
would allow multiple uploads per comment, I had to separate the uploads
and comments into two different tables, which created the problems I am
describing.
Models
------
class Comment < ActiveRecord::Base
belongs_to :board
has_many :uploads, :dependent => :destroy
end
class Upload < ActiveRecord::Base
belongs_to :comment
end
Controller
----------
def index
if request.post?
comment = @board.comments.build(params[:comment])
if comment.save
upload = comment.uploads.create(params[:upload])
redirect_to "/#{@board.path}"
end
end
end
--
Posted via http://www.ruby-forum.com/.
In fact, how the hell am I supposed even theoretically pull this off? The image needs to reference the comment it belongs to during its validation. However, I cannot reference the comment until the comment is saved. But I should not save the comment until the image is validated. Catch 22. Maybe my entire way of going about this is incorrect. -- Posted via http://www.ruby-forum.com/.
Try validates_associated
http://api.rubyonrails.com/classes/ActiveRecord/Validations/
ClassMethods.html#M000820
- dan
--
Dan Kohn <mailto:dan@dankohn.com>
<http://www.dankohn.com/> <tel:+1-415-233-1000>
On Jul 22, 2006, at 6:29 PM, Eleo wrote:
> In fact, how the hell am I supposed even theoretically pull this off?
>
> The image needs to reference the comment it belongs to during its
> validation. However, I cannot reference the comment until the comment
> is saved. But I should not save the comment until the image is
> validated. Catch 22.
>
> Maybe my entire way of going about this is incorrect.
>
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
I looked at that, but I didn''t really understand it. For example, what if my validation of the Upload object involves looking at the Comment object? I can''t do it, as far as I know, since te association isn''t real until the Comment object is saved and has an ID. So if I need to look at any of the Comment object''s attributes within the Upload model I cannot, since I haven''t saved the Comment object. Dan Kohn wrote:> Try validates_associated > http://api.rubyonrails.com/classes/ActiveRecord/Validations/ > ClassMethods.html#M000820 > > - dan > -- > Dan Kohn <mailto:dan@dankohn.com> > <http://www.dankohn.com/> <tel:+1-415-233-1000>-- Posted via http://www.ruby-forum.com/.
The way to get a feel for this is to create your models, and then run
script/console. From there. you can create your objects, and try
different combinations of method names to see what works. This will
give you the realtime insight into how Rails deals with attributes
which you can then use for writing your custom validation.
- dan
--
Dan Kohn <mailto:dan@dankohn.com>
<http://www.dankohn.com/> <tel:+1-415-233-1000>
On Jul 22, 2006, at 7:39 PM, Eleo wrote:
> I looked at that, but I didn''t really understand it.
>
> For example, what if my validation of the Upload object involves
> looking
> at the Comment object? I can''t do it, as far as I know, since te
> association isn''t real until the Comment object is saved and has
an
> ID.
> So if I need to look at any of the Comment object''s attributes
within
> the Upload model I cannot, since I haven''t saved the Comment
object.
>
> Dan Kohn wrote:
>> Try validates_associated
>> http://api.rubyonrails.com/classes/ActiveRecord/Validations/
>> ClassMethods.html#M000820
>>
>> - dan
>> --
>> Dan Kohn <mailto:dan@dankohn.com>
>> <http://www.dankohn.com/> <tel:+1-415-233-1000>
>
>
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
I cannot find any documentation on this sort of thing.
It seems like an unsaved object does not have an ID when it is built;
but at some point between when it is created and saved it gains one.
Associations don''t work properly until it has one. My Upload object
doesn''t know which Comment object it belongs to until Comment has an ID
number; and again, I don''t want to save EITHER object until BOTH are
validated, which has led to a headache indeed.
I cannot reference an associated comment from my Upload model within the
before_validation_on_create method, but I CAN do so within the
before_create method. Right now I have something sort-of-working. What
I have is like this. I have changed my forms so that my file field is
comment[upload] instead of upload[upload]:
class Comment < ActiveRecord::Base
belongs_to :board
has_many :uploads, :dependent => :destroy
acts_as_tree :order => "created_on ASC", :dependent
=>
:destroy
validates_associated :uploads
def upload=(upload)
uploads.build({:upload => upload}) if upload.size > 0
end
end
That catches the uploaded file and sends it to the Upload model ->
class Upload < ActiveRecord::Base
belongs_to :comment
def upload=(upload)
@upload = upload
end
def before_validation_on_create
create_image
end
def create_image
#this is some RMagick nonsese.
end
def before_create
@thumbnail = ImageList.new.from_blob(@image.first.to_blob)
if !comment.parent_id
x = comment.board.setting(:parent_thumbnail_at_width)
y = comment.board.setting(:parent_thumbnail_at_height)
else
x = comment.board.setting(:reply_thumbnail_at_width)
y = comment.board.setting(:reply_thumbnail_at_height)
end
self[:thumbnail_width] = @thumbnail.columns
self[:thumbnail_height] = @thumbnail.rows
if @thumbnail.columns > x or @thumbnail.rows > y
@thumbnail.change_geometry!("#{x}x#{y}") {|cols, rows, img|
img.resize!(cols, rows)}
end
end
end
As you can see, it was imortant that I could reference the associated
comment, because that determined the size of the thumbnail, which I
needed to save to the uploads table.
So I''m closer than when I was before; but still have a long way to go.
For example, I''m only dealing with one uploaded file at a time, when I
need to be dealing with multiple uploads :(
--
Posted via http://www.ruby-forum.com/.
If you do comment.valid? (and ignore the results), are you then able
to do the validations you want?
- dan
--
Dan Kohn <mailto:dan@dankohn.com>
<http://www.dankohn.com/> <tel:+1-415-233-1000>
On Jul 22, 2006, at 9:45 PM, Eleo wrote:
> I cannot find any documentation on this sort of thing.
>
> It seems like an unsaved object does not have an ID when it is built;
> but at some point between when it is created and saved it gains one.
> Associations don''t work properly until it has one. My Upload
object
> doesn''t know which Comment object it belongs to until Comment has
> an ID
> number; and again, I don''t want to save EITHER object until BOTH
are
> validated, which has led to a headache indeed.
>
> I cannot reference an associated comment from my Upload model
> within the
> before_validation_on_create method, but I CAN do so within the
> before_create method. Right now I have something sort-of-working.
> What
> I have is like this. I have changed my forms so that my file field is
> comment[upload] instead of upload[upload]:
>
> class Comment < ActiveRecord::Base
> belongs_to :board
> has_many :uploads, :dependent => :destroy
> acts_as_tree :order => "created_on ASC", :dependent
=>
> :destroy
> validates_associated :uploads
>
> def upload=(upload)
> uploads.build({:upload => upload}) if upload.size > 0
> end
> end
>
> That catches the uploaded file and sends it to the Upload model ->
> class Upload < ActiveRecord::Base
> belongs_to :comment
>
> def upload=(upload)
> @upload = upload
> end
>
> def before_validation_on_create
> create_image
> end
>
> def create_image
> #this is some RMagick nonsese.
> end
>
> def before_create
> @thumbnail = ImageList.new.from_blob(@image.first.to_blob)
>
> if !comment.parent_id
> x = comment.board.setting(:parent_thumbnail_at_width)
> y = comment.board.setting(:parent_thumbnail_at_height)
> else
> x = comment.board.setting(:reply_thumbnail_at_width)
> y = comment.board.setting(:reply_thumbnail_at_height)
> end
>
> self[:thumbnail_width] = @thumbnail.columns
> self[:thumbnail_height] = @thumbnail.rows
>
> if @thumbnail.columns > x or @thumbnail.rows > y
> @thumbnail.change_geometry!("#{x}x#{y}") {|cols, rows, img|
> img.resize!(cols, rows)}
> end
> end
> end
>
> As you can see, it was imortant that I could reference the associated
> comment, because that determined the size of the thumbnail, which I
> needed to save to the uploads table.
>
> So I''m closer than when I was before; but still have a long way to
go.
> For example, I''m only dealing with one uploaded file at a time,
when I
> need to be dealing with multiple uploads :(
>
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails