update a count

I am wondering how you add a value to an existing object versus
creating a new instance of the object. Specifically, I have a button
to klap (clap) for a photo like so:

      <%= form_tag( :action => "klap") %>
        <%= hidden_field :photo_id, :value => params[:photo_id] %>
        <%= image_submit_tag("/images/clap.gif", {:alt => 'klap' }) %>
      <%= end_form_tag() %>

Now I want to add one to the klap field for the specific photo_id each
time this button is clicked. Any idea how to do this? this is all i
have for my klap method in the controller right now:

    def klap
    redirect_to :back
  end

I'm assuming i have to find the photo object first, so i was thinking
something along the lines of:
@photo = Photo.find(:all, :conditions => { :photo_id =>
params[:photo_id] })
is this the most efficient way to do this?

Then im assuming its something like @photo.klap.Add... Im just not
sure what the add function looks like. Thanks, Dave

@photo = Photo.find(:all, :conditions => { :photo_id =>
params[:photo_id] })
is this the most efficient way to do this?

this is correct and would work, but for finding a single record just do:

@photo = Photo.find(params[:photo_id])
then
@photo.increment(:klap)
or
@photo.increment!(:klap)

the second variant would save the record

Is the @photo = Photo.find(params[:photo_id]) less efficient? Does it
take longer? b/c otherwise i am getting this error: Unknown key(s):
value31.

Also, the .increment method doesnt seem to be working. i am getting
this error as well:
undefined method `increment' for []:Array

any ideas, thanks.

Is the @photo = Photo.find(params[:photo_id]) less efficient? Does it
take longer? b/c otherwise i am getting this error: Unknown key(s):
value31.

oops, didn't read your code properly. you're using a form_tag instead of
form_for which is not exactly rails like
I'm not sure, what you get returned in params[:photo_id] in that case
for the hidden field
Photo.find(params[:photo_id]) works only in the case, that
params[:photo_id] contains an (numeric?) id. seems yours contains
value31 instead of 31

Also, the .increment method doesnt seem to be working. i am getting
this error as well:
undefined method `increment' for []:Array

that's with your finder
Photo.find(:all,...) will return an array with all photos that match the
search
in that case use @photo[0].increment(:klap)
or use:
Photo.find(:first, :conditions => {:photo_id => params[:photo_id] })
that will return only one record as an object of expected type

This doesnt seem to be working either, says i get a nil object...
Do you know anything about the increment_counter method? this seems
to be what i need, but I cant get it working. the code i have is:

Photo.increment_counter(:klaps, params[:photo_id])

Im not sure if this is how I get the photo object?

Dave Lynam wrote:

This doesnt seem to be working either, says i get a nil object...
Do you know anything about the increment_counter method? this seems
to be what i need, but I cant get it working. the code i have is:

Photo.increment_counter(:klaps, params[:photo_id])

Im not sure if this is how I get the photo object?

On Mar 6, 3:18 am, Thorsten Mueller <rails-mailing-l...@andreas-s.net>

sorry, but you're doing something very wrong here. if you have a nil
object after the find, it didn't find what you expect and no function
will work
increment_counter differs from increment only by using some kind of
caching

increment:
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001438
increment_counter:
http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M001388

as far as i can see, your params[:photo_id] contains something, that
doesn't match your database
you can check this easy enough:
have a look in log/development.log
in this file each call to an action is logged together with params.
there you can see, what is handed to your controller/action for
params[:photo_id]

Ok, this is helpful. First off, is there any way to purge all the
data in the development log. It is very big now. Second, here is the
snippet for my request:

Processing UsersController#klap (for 127.0.0.1 at 2008-03-06 03:42:45)
[POST]
  Session ID: 906f107fa4549404292991c60e696aac
  Parameters: {"x"=>"22", "y"=>"19", "action"=>"klap",
"controller"=>"users", "photo_id"=>{"value31"=>""}}
  e[4;36;1mPhoto Load (0.001000)e[0m e[0;1mSELECT * FROM photos
WHERE (photos.`id` = '--- \n- value31\n- \"\"\n')

Im not sure what is going wrong here but it doesnt look like any
object is being passed back.

Dave Lynam wrote:

Ok, this is helpful. First off, is there any way to purge all the
data in the development log. It is very big now. Second, here is the
snippet for my request:

two ways:
1) open in editor, select all, save
2) rake log:clear
don't delete the file, or you may get some trouble with permissions

Processing UsersController#klap (for 127.0.0.1 at 2008-03-06 03:42:45)
[POST]
  Session ID: 906f107fa4549404292991c60e696aac
  Parameters: {"x"=>"22", "y"=>"19", "action"=>"klap",
"controller"=>"users", "photo_id"=>{"value31"=>""}}
   [4;36;1mPhoto Load (0.001000) [0m [0;1mSELECT * FROM photos
WHERE (photos.`id` = '--- \n- value31\n- \"\"\n')

Im not sure what is going wrong here but it doesnt look like any
object is being passed back.

you get "photo_id"=>{"value31"=>""}} instead of "photo_id"=>"31"
can't work. i think you must replace
<%= hidden_field :photo_id, :value => params[:photo_id] %>
with
<%= hidden_field_tag(:photo_id, params[:photo_id]) %>
if you use form_tag

Awesome, that worked. thanks a lot, you really helped me out. one
last question, mark mentioned above that it is more efficient to use
form_for, is this true? also, i dont know much about ajax, but would
it be better to use form_for to ajax this request? Thanks again.

Actually, one last question before i go to bed. how would i go about
making it so that a user that is signed in (checked by the user_id
in :session) can only do one klap per photo? Would I have to record
which photos a user has made a klap for in the appropriate user object
and then cross reference this to check if they have submitted a klap
or not? Im just wondering if there is any easy way to do this.
thanks for all your time, Dave

Dave Lynam wrote:

Awesome, that worked. thanks a lot, you really helped me out. one
last question, mark mentioned above that it is more efficient to use
form_for, is this true? also, i dont know much about ajax, but would
it be better to use form_for to ajax this request? Thanks again.

yes, whenever you work with ActiveRecord Objects it's much better to use
form_for, since lots of stuff is done by rails in the background,
ensuring, that paths and params work as expected
for ajax calls you would use remote_form_for

Actually, one last question before i go to bed. how would i go about
making it so that a user that is signed in (checked by the user_id
in :session) can only do one klap per photo? Would I have to record
which photos a user has made a klap for in the appropriate user object
and then cross reference this to check if they have submitted a klap
or not? Im just wondering if there is any easy way to do this.
thanks for all your time, Dave

you would need an intermediate table to store this relation between
users and photos, since for each combination of user/photo there must be
an entry
that would be an has_and_belongs_to_many association
quite some work for such a simple thing

ok, cool, that helps. so i have another database relationship
question. I have a user_id column in my photo_comments table and i
want to link it to my avatar table, which also has a user_id column.
I can't use the belongs to method b/c it would look for an avatar_id
field. I want to display the avatar pictures next to the user's
comments. This is what i have so far:

<% for comment in @comments -%>
  <br/> on <%= comment.created_at.strftime('%m-%d-%Y') %> @ <%=
comment.created_at.strftime('%I:%M') %> <%= comment.user.screen_name
%> said:
br/><%= white_list comment.comment %><br/>
<% end -%>

any suggestions are greatly appreciated.

ok, cool, that helps. so i have another database relationship
question. I have a user_id column in my photo_comments table and i
want to link it to my avatar table, which also has a user_id column.
I can't use the belongs to method b/c it would look for an avatar_id
field. I want to display the avatar pictures next to the user's
comments. This is what i have so far:

yes, you can use it

in photo_comments you must have something like
belongs_to :user

and in user:
has_one :avatar

you can add to photo_comments:
has_one :avatar, :through => :user

and access with

comment.avatar.image_file_name (or whatever column the filename is
stored in)
in the view something like:
<%= image_tag("/path/#{comment.avatar.image_file_name}") %>

should work

(if this doesn't work, pls post some details about those three models,
the relevant associations and column names)

hmmm, im getting an error that says:

ArgumentError in UsersController#test
Unknown key(s): through

this is my test method is UserController:
  def test
    @comments = PhotoComment.find(:all, :conditions => { :photo_id =>
params[:photo_id] })
  end

class PhotoComment < ActiveRecord::Base
  belongs_to :user
  has_one :avatar, :through => :user
end

not sure what this means.

checked that, the :through exists only for belongs_to and has_many
but never mind, remove the has_one, you can just use

comment.user.avatar

should work as good as the other variation

sweet, i removed the through and just left has_one :avatar in the
photoComment model and it worked perfectly. thanks so much.