Store several text_field strings to array Rails 3

I'm trying to store some strings from a couple of text_fields that i have into an array, and then save it to the DB. I have a column named "opening_hours" wich I've tried to separate into 2 different attributes using virtual attributes like this:

Model

class Venue < ActiveRecord::Base
    attr_accessible :opening_hours, :start_time, :end_time
    attr_writer :start_time, :end_time

    def start_time
        @start_time.nil? ? @start_time : opening_hours.to_s.split("-").first  
    end

    def end_time
        @end_time.nil? ? @end_time : opening_hours.to_s.split("-").last
    end
end

The idea is that you type in a start_time and an end_time like this:

View

<%= form_for @venue do |v| %>
    <p><%= v.label "Monday" %><%= v.text_field :start_time %>-<%= v.text_field :end_time %><p/>
    <p><%= v.label "Tuesday" %><%= v.text_field :start_time %>-<%= v.text_field :end_time %><p/>
    <p><%= v.label "Wednesday" %><%= v.text_field :start_time %>-<%= v.text_field :end_time %><p/>
<% end %>

The array should look something like this in the DB:

{08-12|09-14|07-13}

With the "|" separating the different days of the week.

I've tried a couple of things in the controller like:

Controller

class VenuesController < ApplicationController
    def new
        @venue = Venue.new
    end

    def create
        @venue = Venue.new(params[:venue])
        @total_time = params[:venue][:start_time]+"-"+params[:venue][:end_time]
        @venue.opening_hours = @total_time.map {|t| [t.start_time, t.end_time]}
    if @venue.save
        redirect_to venue_path(@venue), :notice => "Success!"
    else
        render 'new'
    end  
end

But nothing seems to work... either it just saves start_time and end_time from the last day, or nothing gets saved at all.

Answers


I perhaps may have misunderstood, but...

In your create action, there is no @venue.save - this could be why you are not seeing anything saved.

class VenuesController < ApplicationController

def new
    @venue = Venue.new
end

def create
    @venue = Venue.new(params[:venue])
    @total_time = params[:venue][:start_time]+"-"+params[:venue][:end_time]
    @venue.opening_hours = @total_time.map {|t| [t.start_time, t.end_time]}
    @venue.save
end

end


Your solution will not work, since you place three text-fields each pointing to the same field. Rails will just take the last value.

Rails will use the name of the input field to construct the parameters hash you receive at the server. Since the fields have the same name, only one value will remain.

The solution is pretty simple: using the same rails standards, we can change the name of the input fields so rails will handle it as a hash.

<p>
  <%= v.label "Monday" %>
  <%= text_field :venue, 'start_time[][monday]', :value => '07' %>
  <%= text_field :venue, 'end_time[][monday]', :value => '21' %>
<p/>
<p>
  <%= v.label "Tuesday" %>
  <%= text_field :venue, 'start_time[][tuesday]', :value => '07' %>
  <%= text_field :venue, 'end_time[][tuesday]', :value => '09' %>
<p/>

Since end_time and start_time is not a array, I have to fake it a bit, so I use a manual text_field, use as object-name venue so it will be grouped with the rest of the parameters for your venue. Then I build the name, so rails will compose a hash with the values entered. Note, you have to explicitly define a value, or this will not work.

Then, in the controller, you will have to add some code to

  • when editing, convert the array-string to values in your form
  • when saving, convert the recevied hash to a string you can save.

Note: if you do not, it will save the serialized hash, which might just be enough already.


Need Your Help


About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.