3

I'm having problems saving my data of arrays into the database. Currently, I am using a nested form and have 3 models as shown below.

deal.rb

class Deal < ActiveRecord::Base
  has_many :deal_days, :dependent => :destroy
  accepts_nested_attributes_for :deal_days, allow_destroy: true
end


deal_day.rb

class DealDay < ActiveRecord::Base
  belongs_to :deal
  has_many :deal_times, :dependent => :destroy
  accepts_nested_attributes_for :deal_times, allow_destroy: true
end


deal_time.rb

class DealTime < ActiveRecord::Base
  belongs_to :deal_day
end

My objective is to allow users to select multiple days where the deal is ongoing in a checkbox. For example if a user selects Monday and Tuesday, I want the array to have monday and tuesday in it. Shown below is my current database for deal_day:

create_table "deal_days", force: true do |t|
    t.integer  "deal_id"
    t.string   "day",        default: [], array: true
    t.datetime "created_at"
    t.datetime "updated_at"
end

The form for deal_day is as follows in a file called _deal_day_fields:

<fieldset>
  Enter Days (e.g Mon - Fri)<br>
  <td><input type = "checkbox" name = "day[]" value = "Mon" /></td>
  <td><input type = "checkbox" name = "day[]" value = "Tue" /></td>
  <td><input type = "checkbox" name = "day[]" value = "Wed" /></td>
  <td><input type = "checkbox" name = "day[]" value = "Thur" /></td>
  <td><input type = "checkbox" name = "day[]" value = "Fri" /></td>
  <td><input type = "checkbox" name = "day[]" value = "Sat" /></td>
  <td><input type = "checkbox" name = "day[]" value = "Sun" /></td>
  <%= link_to "Delete", '#', class: "remove_fields" %><br>
  <%= f.hidden_field :_destroy %>
  <%= f.fields_for :deal_times do |builder| %>
      <%= render 'deal_time_fields', f: builder %>
  <% end %>
  <%= link_to_add_fields "Add another time period", f, :deal_times %>
</fieldset>

For the deal controller params, I have set it to be so:

    params.require(:deal).permit(:name_of_deal, :type_of_deal, :description, :start_date, :expiry_date, :location, :t_c,
                             :pushed,:redeemable, :multiple_use, :image,
                             deal_days_attributes: [:id, {day: []}, :_destroy,
                                                    deal_times_attributes: [:id, :started_at, :ended_at, :_destroy]])

When, I run the form, all my data is saved properly into the database except for the array of :day. It is saved into the database as [].
I would appreciate it if anyone can tell me my mistake. Thank you!

9
  • this link may help you stackoverflow.com/questions/6360739/… Commented Sep 4, 2015 at 17:30
  • If i'm right test by selecting sunday, this will save in db, because if you have N name = "day[]" name = "day[]" ....... last one will be overridden and sent to db to store. Commented Sep 4, 2015 at 17:38
  • hi @praaveen, I tried what you suggested but it still saves only []. I've read up on the link you posted and if I cannot reach a solution I might just create 7 different attributes to name monday to sunday. Thank you though! Commented Sep 4, 2015 at 17:42
  • check in you controller by printing params. Commented Sep 4, 2015 at 17:45
  • Why do you want to store an array? SQL arrays are a huge pain to query. I'd recommend you store a boolean for each day of the week – you get to keep your checkbox structure, and you have much easier data types to deal with and to query. Commented Sep 4, 2015 at 17:54

1 Answer 1

1

If you want days[] within deal_days in your controllers params as you posted in your strong parameters require/permit statement, you can build this with form helpers (see http://guides.rubyonrails.org/form_helpers.html#building-complex-forms).

Here is what it would look like:

# app/views/deals/_form.html.erb
    ...
    <%= f.fields_for :deal_days do |f_days| %>
        <%= fields_for 'deal[deal_days][]', f_days.object do |f_days_array| %>
            <%= f_days_array.check_box 'Monday' %>
            <%= f_days_array.check_box 'Tuesday' %>
            ...etc..
        <%= f.fields_for :deal_times do |builder| %>
            <%= render 'deal_time_fields', f: builder %>
        <% end %>
    <% end %>

Pretty sure that's it, or pretty close. I based this off of the code in section 7.3 of the Rails guide above. You should definitely read up on that whole page if you are still confused.

Caveat: This solution won't reach your stated objective, because this data is currently associated with the deal, while it needs to be associated with a user in addition to a specific deal/deal day. But that's another problem.

Sign up to request clarification or add additional context in comments.

1 Comment

To further clarify the difference, by setting your inputs to name="day[]", the web browser literally puts them in the root as day[0] = true, day[1] = true. If you had name=deal[deal_day][], you would get deal => {deal_day => {0: true, 1: true, ...}} and what you actually need is deal_day_attributes => {0: true, 1: false}' using the fields_for` builds this automatically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.