Newbie question - how do I add values to a result and save?

Sorry for cross posting this, but I accidentally put this in the Ruby forum first and I think it's more appropriate in RoR.

I know that I'm missing something simple here, but the solution is evading me.

I want to get the values in the fruits field for my first order.

In script console I type this:

Cart.find(:first, :select => "fruits")

=>#(Car fruits: "apple, orange, pear")

Now I want to add grapefruit to that list and save it back into the fruits field.

How can I do that?

I know it's something so basic, but I'm missing it.

Thanks!

I know that I'm missing something simple here, but the solution is evading me.

I want to get the values in the fruits field for my first order.

In script console I type this:

Cart.find(:first, :select => "fruits")

=>#(Car fruits: "apple, orange, pear")

c = Cart.find(:first) c.fruits += ", grapefruit" c.save

Now, that all said, managing a list of line items on a order using a string can be problematic.

You may want to have your Cart have_many LineItems and each line item is a single product, quantity, price... that preferably references a Product model.

or not :slight_smile:

When you use :select to limit the columns retrieved, you might not have a "saveable" record.

Assuming that cart.fruits is a string, then:

  cart = Cart.find(:first)   cart.fruits << ', grapefruit'   cart.save

Since that's "so basic", perhaps the read-only part that :select imposed was the problem. If fruits is something else, provide a bit more detail and I could be a bit more helpful.

-Rob

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com

Philip Hallstrom wrote:

c = Cart.find(:first) c.fruits += ", grapefruit" c.save

Perfect!

Now, that all said, managing a list of line items on a order using a string can be problematic.

Yes, it is problematic, but it's how the application has been set up and I'm not able to change it at this time. Legacy data is fun!

Let me ask one other question, I use that same string to query back a results list. Now I have "apple, orange, pear, grapefruit".

Let's say I want to query that same table and find all of the other orders that contain any one of these items. Given what I have, is my only option to write a gsub method that's ugly and create a custom finder for it?

I know, the throwing good at bad continues.

Rob Biedenharn wrote:

Since that's "so basic", perhaps the read-only part that :select imposed was the problem. If fruits is something else, provide a bit more detail and I could be a bit more helpful.

I did have an initial problem with a non-savable record. I had to pull the entire record and remove the :select.

My brain is trying to put many things together and things are getting very lost in the process.

Thanks for your help.

Philip Hallstrom wrote:

c = Cart.find(:first) c.fruits += ", grapefruit" c.save

Perfect!

Now, that all said, managing a list of line items on a order using a string can be problematic.

Yes, it is problematic, but it's how the application has been set up and I'm not able to change it at this time. Legacy data is fun!

For various definitions of "fun" :slight_smile:

Let me ask one other question, I use that same string to query back a results list. Now I have "apple, orange, pear, grapefruit".

Let's say I want to query that same table and find all of the other orders that contain any one of these items. Given what I have, is my only option to write a gsub method that's ugly and create a custom finder for it?

search = "grape" Cart.find(:all, :conditions => ['fruits like ?', "%#{search}%"])

will return all Cart's whose fruits have "grape" in them somewhere.

Philip Hallstrom wrote:

search = "grape" Cart.find(:all, :conditions => ['fruits like ?', "%#{search}%"])

will return all Cart's whose fruits have "grape" in them somewhere.

What if I want to search for the orders that have any of the fruits in my string?

An equivalent "where" clause would be "where fruits = 'apple' or fruits = 'orange' or fruits = 'grapefruit'"

To find all orders that have *any* of those fruits:

Cart.find(:all, :conditions => ['fruits like ? OR fruits like ? OR fruits like ?',                  '%apple%', '%orange%', '%grapefruit%']           )

Programmatically,

search = "apple, orange, grapefruit" search_fruit = search.split(/, /) Cart.find(:all, :conditions => [(['fruits like ?']*search_fruit.size).join(' OR '),                  *(search_fruit.map{|f| "%#{f}%"})] )

So you can probably see why "fun" has to be qualified when talking about legacy data.

-Rob

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com

Rob Biedenharn wrote:

Programmatically,

search = "apple, orange, grapefruit" search_fruit = search.split(/, /) Cart.find(:all, :conditions => [(['fruits like ?']*search_fruit.size).join(' OR '),                  *(search_fruit.map{|f| "%#{f}%"})] )

I think that I'm close, but split is only splitting the first value in the string from all of the others that are still strung together.

Post a real string to be sure, but I suspect that the /, / (comma space) isn't matching between the other fruits. Try /,\s*/ to get (comma followed by optional whitespace)

-Rob

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com