0

I'm trying to create multiple objects at once from the same form like this:

<div class="container">
 <%= form_tag store_opening_hours_create_path do %>
  <% @opening_hour.each do |hour| %>
  <%= fields_for 'opening_hour = []', hour do |p|%>


  <div class="row">
   <table class="table">
     <thead>
     <tr>
       <th>Select a day</th>
       <th>Opens at</th>
       <th>Closes at</th>
     </tr>
     </thead>
     <tbody>
     <tr>
       <td>
       <%= p.select :day, [['Monday', 1], ['Tuesday', 2], ['Wednesday', 3],
                             ['Thursday', 4], ['Friday', 5], ['Saturday', 6],['Sunday', 7]], {}, class: "form-control" %>
    </td>

    <td>
      <%= p.select :opens, [['12:00AM', 12], ['13:00PM', 13], ['14:00PM', 14], ['15:00PM', 15], ['16:00PM', 16], ['17:00PM', 17],
                               ['18:00PM', 18], ['19:00PM', 19], ['20:00PM', 20], ['21:00PM', 21], ['22:00PM', 22], ['23:00PM', 23], ['24:00PM', 24],
                               ['01:00AM', 1], ['02:00AM', 2], ['03:00AM', 3], ['04:00AM', 4], ['05:00AM', 5], ['06:00AM', 6], ['07:00AM', 7],
                               ['08:00AM', 8], ['09:00AM', 9], ['10:00AM', 10], ['11:00AM', 11], ['00:00', 0]],
                      {}, class: "form-control" %>

    </td>

    <td>
      <%= p.select :closes, [['12:00AM', 12], ['13:00PM', 13], ['14:00PM', 14], ['15:00PM', 15], ['16:00PM', 16], ['17:00PM', 17],
                                ['18:00PM', 18], ['19:00PM', 19], ['20:00PM', 20], ['21:00PM', 21], ['22:00PM', 22], ['23:00PM', 23], ['24:00PM', 24],
                                ['01:00AM', 1], ['02:00AM', 2], ['03:00AM', 3], ['04:00AM', 4], ['05:00AM', 5], ['06:00AM', 6], ['07:00AM', 7],
                                ['08:00AM', 8], ['09:00AM', 9], ['10:00AM', 10], ['11:00AM', 11], ['00:00', 0]],
                      {}, class: "form-control" %>

    </td>

  </tr>

    <%= p.hidden_field :store_id, value: current_store.id %>
  <% end %>
<% end %>
  </tbody>
</table>
</div>


  <%= submit_tag 'Submit, %>
  <% end %>

 </div>

and this what have inside the controller:

 def new
   @opening_hour = []
    7.times do
     @opening_hour << OpeningHour.new
    end
    render :template => "stores/opening_hours/new"
 end

 def create
   params["opening_hour"].each do |hour|
     if hour["day"] != "" || hour["closes"] != "" || hour["opens"] != ""
       OpeningHour.create(opening_hour_params(hour))
      redirect_to(root_path)
   return
     end
   end
end

 def opening_hour_params(my_params)
   my_params.permit(:store_id, :day, :closes, :opens, :valid_from, :valid_through)
 end

But when I hit submit I get the following error:

NoMethodError in OpeningHoursController#create undefined method 'each' for nil:NilClass

and this is what i get inside the rails console:

Started POST "/store/opening_hours/create" for 127.0.0.1 at 2018-02-23 12:04:07 +0200
Processing by OpeningHoursController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"pQP2xegYmfllUQUpHsWzqy7sEanpMA5cV5Kaiye1s7ogunQ2Et3oKKZnKr7VAsebpp6bxQuDbH07eCJHp4bSdQ==", "opening_hour = "=>[{"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}], "commit"=>"Submit"}
Completed 401 Unauthorized in 2ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method 'each' for nil:NilClass):
  app/controllers/opening_hours_controller.rb:18:in 'create'

After debugging a little bit inside the create method where the error is happening, I found out that the params["opening_hour"] returns nil and thats why it returns this error.
Any ideas why this is happening and how I can make this work?

Update 1

Started POST "/store/opening_hours/create" for 127.0.0.1 at 2018-02-23 13:22:19 +0200
Processing by OpeningHoursController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"rvNr5bq7DmZtpiMPaE6qYMN2dE7+qarFI2c2e8kedYIrSukWQH5/t66QDJijid5QSwT+IhwayORPjY63SS0UTQ==", "opening_hour = "=>[{"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}, {"day"=>"1", "opens"=>"12", "closes"=>"12", "store_id"=>"1"}], "commit"=>"Update Account"}
   (0.1ms)  BEGIN
  Store Load (0.3ms)  SELECT  "stores".* FROM "stores" WHERE "stores"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  OpeningHour Exists (0.6ms)  SELECT  1 AS one FROM "opening_hours" WHERE "opening_hours"."opens" = $1 AND "opening_hours"."store_id" = $2 AND "opening_hours"."day" = $3 LIMIT $4  [["opens", "12:00:00"], ["store_id", 1], ["day", 1], ["LIMIT", 1]]
  OpeningHour Exists (0.4ms)  SELECT  1 AS one FROM "opening_hours" WHERE "opening_hours"."closes" = $1 AND "opening_hours"."store_id" = $2 AND "opening_hours"."day" = $3 LIMIT $4  [["closes", "12:00:00"], ["store_id", 1], ["day", 1], ["LIMIT", 1]]
   (0.2ms)  ROLLBACK

Update 2

Processing by OpeningHoursController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"rvNr5bq7DmZtpiMPaE6qYMN2dE7+qarFI2c2e8kedYIrSukWQH5/t66QDJijid5QSwT+IhwayORPjY63SS0UTQ==", "opening_hour = "=>[{"day"=>"1", "opens"=>"8", "closes"=>"17", "store_id"=>"1"}, {"day"=>"2", "opens"=>"8", "closes"=>"17", "store_id"=>"1"}, {"day"=>"3", "opens"=>"8", "closes"=>"17", "store_id"=>"1"}, {"day"=>"4", "opens"=>"8", "closes"=>"17", "store_id"=>"1"}, {"day"=>"5", "opens"=>"8", "closes"=>"17", "store_id"=>"1"}, {"day"=>"6", "opens"=>"0", "closes"=>"0", "store_id"=>"1"}, {"day"=>"7", "opens"=>"0", "closes"=>"0", "store_id"=>"1"}], "commit"=>"Update Account"}
   (0.2ms)  BEGIN
  Store Load (0.4ms)  SELECT  "stores".* FROM "stores" WHERE "stores"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  OpeningHour Exists (0.4ms)  SELECT  1 AS one FROM "opening_hours" WHERE "opening_hours"."opens" = $1 AND "opening_hours"."store_id" = $2 AND "opening_hours"."day" = $3 LIMIT $4  [["opens", "08:00:00"], ["store_id", 1], ["day", 1], ["LIMIT", 1]]
  OpeningHour Exists (0.4ms)  SELECT  1 AS one FROM "opening_hours" WHERE "opening_hours"."closes" = $1 AND "opening_hours"."store_id" = $2 AND "opening_hours"."day" = $3 LIMIT $4  [["closes", "17:00:00"], ["store_id", 1], ["day", 1], ["LIMIT", 1]]
  SQL (6.5ms)  INSERT INTO "opening_hours" ("store_id", "day", "closes", "opens", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"  [["store_id", 1], ["day", 1], ["closes", "17:00:00"], ["opens", "08:00:00"], ["created_at", "2018-02-23 11:30:04.441164"], ["updated_at", "2018-02-23 11:30:04.441164"]]
   (0.8ms)  COMMIT

Update 3

opening_hour.rb

class OpeningHour < ApplicationRecord
  belongs_to :store

  validates_presence_of :day, :closes, :opens, :store_id
  validates_inclusion_of :day, :in => 1..7
  validate :opens_before_closes
  validate :valid_from_before_valid_through

 # sample validation for better user feedback
 validates_uniqueness_of :opens, scope: [:store_id, :day]
 validates_uniqueness_of :closes, scope: [:store_id, :day]

 protected
  def opens_before_closes
    errors.add(:closes, I18n.t('errors.opens_before_closes')) if opens && closes && opens >= closes
  end

  def valid_from_before_valid_through
    errors.add(:valid_through, I18n.t('errors.valid_from_before_valid_through')) if valid_from && valid_through && valid_from >= valid_through
  end

end

8
  • according to your console params you receive params in "opening_hour = " => not in "opening_hour" => you need to fix this first. Commented Feb 23, 2018 at 10:38
  • Thanks for the reply@Pardeep Saini... the error doesn't show up now. But it doesn't create the objects, I'm guessing that it has something to do with controller method def opening_hour_params(my_params)' and that the name of the prams now is opening_hour =`... any ideas? Commented Feb 23, 2018 at 11:18
  • can you show me what you receive as params in create method. Commented Feb 23, 2018 at 11:20
  • Yes of course! please check out my question, I have update it! sorry for the format though, I cant get it to show better! Commented Feb 23, 2018 at 11:25
  • you record is created and rollback i.e OpeningHour Exists (0.4ms) and (0.2ms) ROLLBACK because you are trying to save the identical records. All records in opening_hour array are identical. Commented Feb 23, 2018 at 11:28

1 Answer 1

1

You are trying to save identical records . You need to add validation on frontend for validation of identical records.

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

Comments

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.