Learner
Learner

Reputation: 4636

how to append a string value to existing column value in ruby?

I have a method in my ruby model like the following:

def testing
  update_stock = Stock::Detail.find(stock) # (Assume I have a stock id.)
  update_stock.update_attributes(details: "dashboard")
end

The above is working fine. But If the details has a value already like 'table,chair' as a string. How can I append the 'dashboard' to the details field. Currently the update_attributes remove the old value and update the new value. I want to append the value to existing value.

Update Question:

If I declare the string value into the variable like

detail_value = 'Code: 123AB, dashboard, code: 1235Q, table, chair'

def testing
  update_stock = Stock::Detail.find(stock) # (Assume I have a stock id.)
  update_stock.update_attributes(details: detail_value)
end

I want to append the details column where the above code is not exists already.

Update for Max comments

For example, my details column has a value like

'Code: 123AB, dashboard, code: 1235Q, table, chair'   # Before

and my parameter is 'Code:123AB, dashboard' # Parameter

I want to remove the parameter from the string value and update to the database column.

So my column value would be 'code: 1235Q, table, chair'

Thanks

Upvotes: 1

Views: 1022

Answers (2)

Max Williams
Max Williams

Reputation: 32933

As an alternative to Marek's answer, you could add a "setter" method which appends the string rather than replaces it. Then you can just do the standard update_attributes in your controller: personally i think it's good to keep the controller actions as standardised as possible. eg

# in Stock::Detail

#setter method
def append_details=(s)
  self.details ||= ""
  unless self.details.include?(s)
    self.details << " #{s}"
  end
end

#getter version of above - just shows the value of details
def append_details
  self.details || ""
end    

Now in your view, you can say, eg

<%= form_for @detail do |f| %>
    <label>Details <%= f.input :append_details %>
    ...

Now you can just do the standard behaviour in your create controller, eg

@detail.update_attributes(params[:detail])

Couple of notes:

1) Personally i think you're asking for trouble having a model called Detail which has a method .details - this is confusing.

2) Have a look at serialize - it might be better to save this as an array of strings, rather than a string. http://api.rubyonrails.org/classes/ActiveModel/Serialization.html

EDIT - similar method to remove a substring from the field.

# in Stock::Detail

#setter method
def subtract_details=(s)
  self.details ||= ""
  self.details = self.details.gsub(s,"").gsub(/\s+/, " ").strip
end

#getter version of above - just shows the value of details
def subtract_details
  self.details || ""
end 

The .gsub(/\s+/, " ").strip bit just tidies up the string, converting multiple spaces to single spaces, and getting rid of leading/trailing spaces.

Upvotes: 1

Marek Lipka
Marek Lipka

Reputation: 51151

Why not like this:

def testing
  update_stock = Stock::Detail.find(stock)
  update_stock.details += 'dashboard'
  update_stock.save
end

Update answer: maybe check if this string occurs in details:

update_stock.details += 'dashboard' unless update_stock.details =~ /dashboard/

Upvotes: 4

Related Questions