0

I am looping through a list of objects and changing some of the values. When I output the value into the logger, I see the changed values, but when then on the resulting page, the changes do not get saved.

Here is my loop:

@dis.each do |d|
  temp = d.notes.inspect

  #Now check the length of the temp variable
  temp.length > 25 ? temp = temp[0,25] :  nil

  d.notes = temp
end

How do I change it so that the new values of temp get saved in the @dis object?

Thanks!

fl00r
  • 82,987
  • 33
  • 217
  • 237
Awesomeness
  • 2,501
  • 3
  • 18
  • 18
  • @fl00r the view is a bit spaghettish with partials, but why wouldn't the loop be enough code? Is it not possible to just reset the object with the new value? – Awesomeness Apr 30 '12 at 15:06

2 Answers2

3

You can get the result you want using collect! or map! to modify the array in-place:

https://stackoverflow.com/a/5646754/643500

x = %w(hello there world)
x.collect! { |element|
  (element == "hello") ? "hi" : element
}
puts x

Edit:

So for your code it will look like

@dis.collect! do |d|
  temp = d.notes.inspect

  #Now check the length of the temp variable
  temp.length > 25 ? temp = temp[0,25] : temp = nil

  d.notes = temp
end

Edit:

Full code that worked here. Make sure you have :notes with getters and setters. Read about cattr_accessor, attr_accessor and attr_accessible

class TestClass
  @note
  def initialize note
    @note = note
  end
  def get_note
    @note
  end
  def set_note note
    @note = note
  end
end

@dis = Array.new
@dis << TestClass.new("yo yo")
@dis << TestClass.new("1 2 3 4 5 6 7 8 9 10 6 7 8 9 10 6")
@dis << TestClass.new("a b c")

@dis.collect! do |d|
  temp = d.get_note.inspect

  #Now check the length of the temp variable
  d.get_note.inspect.length > 25 ? d.set_note(temp[0,25]) : d.set_note(nil)

end


puts "#{@dis}"
Community
  • 1
  • 1
Sully
  • 14,672
  • 5
  • 54
  • 79
  • I am kind of new to some of the ruby techniques. Here I am just looping through an object. How can I just change the individual field and reset that object in the list of object? – Awesomeness Apr 30 '12 at 15:03
  • I mean...does "puts x" accomplish that? – Awesomeness Apr 30 '12 at 15:04
  • puts x #just proves it updated the values. So, its just printing it. The key is that collect and map iterates over the actual object, therefore allows us to update it. – Sully Apr 30 '12 at 15:10
  • But I am not sure how that would work in my case since I need to replace it within the object. Any idea what I should try? – Awesomeness Apr 30 '12 at 15:11
  • Thanks - I tried what you suggest, but it doesn't end up propagating the value to the view...i'll keep researching. – Awesomeness Apr 30 '12 at 15:15
  • Check the list after you update before ending the function. Now, check the value after you redirect your view. It will most likely reset or based on the initialize method or :before_filter methods could reset it. A way to hold the value is to use instance variables like: cattr_accessor :my_list then use it as MyController.my_list and save it there. – Sully Apr 30 '12 at 15:17
  • I just checked right after the loop, and the object @dis does not get saved with new values :( – Awesomeness Apr 30 '12 at 15:22
1

It looks like you're trying to truncate the notes attribute.

This should be enough:

@dis.each do |d|
  d.notes = d.notes.inspect[0,25]
end

Because of the assignment, this will alter the objects inside the array in place, but it won't change the array object itself. map! and collect! (they're aliases), will alter the array itself, but not he objects inside it. map and collect will return a new array all together.

If your problem is that it isn't saved into the database, then you should put a d.save in there somewhere.

If it's just for presenting, why not truncate the values when presenting them in the view?

<%= truncate d.notes, :length => 25 %>
iain
  • 16,204
  • 4
  • 37
  • 41