updating attributes in active record - simple q I think!

Hi all,

I have a model Events, with the attributes relating to events, event
name / band / date etc, and venue.

I also have a model called venue, and all the different saved venues are
presented as a dropdown list when creating a new event.

Attributes associated with the saved venue such as latitude and
longitude are then copied over to the event being saved. This works
fine.

However when I go back to the saved event and try to update it, if I
choose a new venue from the list and press update, the latitude /
longitude values aren't getting copied over. I've tried many possible
solutions, sometimes with temporary success (on first try), but none of
them work continuously, here's what I've tried

<code>
EventController

def update

    @event = Event.find(params[:id])
    @venue = (Venue.where(:venueName => @event.venue))[0]

   if @venue
  @event.city_location = @venue.city_location
  @event.longitude = @venue.longitude
  @event.latitude = @venue.latitude
   end

    if @event.update_attributes(params[:suggested_event])

      flash[:success] = "SuggestedEvent updated."
      redirect_to @event

</code>

Values didn't change.

I tried this in the console and got the error

NameError: undefined local variable or method `params' for
#<Object:0x100177298>
  from (irb):7

and in the console removing the word 'params' seemed to do the trick, so
updated the code to
<code>
...
    if @event.update_attributes(:suggested_event)
....
</code>

This worked once, then never again!!!

I've also tried

<code>

    @event = Event.find(params[:id])
    @venue = (Venue.where(:venueName => @event.venue))[0]

  if @venue
  @event.update_attributes(:city_location => @venue.city_location)
  @event.update_attributes(:longitude => @venue.longitude)
  @event.update_attributes(:latitude => @venue.latitude)
  end

    if @event.update_attributes(params[:suggested_event])

      flash[:success] = "SuggestedEvent updated."
      redirect_to @event
</code>

but again the values didn't change.

Could anyone please tell me

a - how to update values of active record properly in this case?
b - why console doesn't recognise 'params'
and
c - why on earth might the 2nd try have worked once, and then never
again! (unless it was a mirage?!)

Any help massively appreciated

Mike

ps. I deliberately wanted the values to be copied over, so that
afterwards I could 'tweak' each event individually, for example by
having a very slightly different latitude on multiple events in the same
venue means on my google map view of how to get to them, I get multiple
pins!!

but again the values didn't change.

Could anyone please tell me

a - how to update values of active record properly in this case?

Either params doesn't contain what you think it is and so the call to
update_attributes doesn't do anything, or you've got validations
preventing the record from saving or you've got some attr_protected/
attr_accessible calls somewhere. Other than that
@event.update_attributes(params[:suggested_event]) is fine, as long as
params[:suggested_event] contains the right thing.

b - why console doesn't recognise 'params'

because params is an instance method that controllers have. It would
be pretty meaningless in the console, since there is no associated
request.

and
c - why on earth might the 2nd try have worked once, and then never
again! (unless it was a mirage?!)

Must have been a mirage - it's completely meaningless.

Fred

Ok,

thanks for your help.

so I'm trying to get one of the values out of 'params' before updating
the record, and then use the value of the param to change other params
before saving the record.

    # the record I'm saving
    @event = Event.find(params[:id])

    # look at different model called venue to see if there are any with
the same name
    @venue = (Venue.where(:venueName => @event.venue))[0]

  # if there are venues of the same name as the event I'm trying to
save, copy longitude and latitude values from venue to event.
  if @venue
  @event.update_attributes(:city_location => @venue.city_location)
  @event.update_attributes(:longitude => @venue.longitude)
  @event.update_attributes(:latitude => @venue.latitude)
  end

  #save the event
  if @event.update_attributes(params[:suggested_event])

If I say that the event is at a venue called 'Warehouse 54', I want to
go and search all my saved venues looking for 'venue 54', and then
filling in other values in the 'event' according to what saved for that
venue.

"Either params doesn't contain what you think it is and so the call to
update_attributes doesn't do anything,"
Params doesn't contain what I want it to - it's not going and filling in
the other values

Any advice on how to look at, and alter the params being updated before
they're updated?

Thanks

sorry "looking for 'venue 54'" should read looking for 'Warehouse 54'

This seems to be working:

Overwrote the update_attributes method in Events Model.

def update_attributes(attributes)

  venueName = attributes[:venue]
  sameVenueName = Venue.where(:venueName => venueName)[0]

  if sameVenueName
  attributes[:city_location] = sameVenueName.city_location
  attributes[:latitude] = sameVenueName.latitude
  attributes[:longitude] = sameVenueName.longitude
  end

  self.attributes = attributes
  save
end

Why are you not just saying event belongs_to venue (venue has_many
events)? Then you do not need to save the venue lat and long in the
event as they will be automatically available as event.venue.latitude
for example. If you do not know how to do this have a look at the
Rails Guide on ActiveRecord relationships.

Colin

Cheers for the tip Colin,

"Why are you not just saying event belongs_to venue (venue has_many
events)?"

I'm still learning all the various options, and that sounds very
interesting, I'd read about associations, and the reason I didn't use
them this time was because I want the ability to be able to 'tweak' the
individual values for each event ever so slightly, for example by having
a slight variation in longitude / latitude means that events shown on a
map are a cluster of pins about the venue, instead of lots of pins on
top of one another. Actually, though this could be more effectively
implemented with a method for adding random variation, in which case
your 'belongs_to - has_many' relationship would actually be very useful.

The other consideration is that I'm downloading the data using xml, I'm
unsure if the associated venue data will be downloaded when I retrieve
the data about events? Any idea how to do this? or is this completed
with

      format.xml { render :xml => @events }
?

cheers,

Mike

I have not used render to xml so I don't know how to do it. I can
guarantee that it is possible and google shows lots of hits. If you
do provide lat and long offsets in the event that are to be added to
those of the venue then you will want to provide access methods in the
event model so that you can say things like @event.latitude where this
is a method of Event that fetches the venue position and adds the
offset. You will then presumably need to put that in the xml. A
quick bit of googling suggests you might want to use xml builder for
this but as I said I have not done such things myself so don't take my
word for it.

Colin