After I, a Rails beginner, associated tables by association I had a lot of trouble not passing the parameters to the action method, so I will write an article. The goal is to give the Place (cafe) information about the menus and output it on the screen.
irb(main):005:0> Place.column_names
=> ["id", "name", "message", "created_at", "updated_at", "user_id"]
irb(main):006:0> Menu.column_names
=> ["id", "title", "price", "message", "created_at", "updated_at", "place_id"]
It will be as above.
The logged-in User posts his favorite cafe → Menu information can also be added to that cafe. It is a function called.
app/models/place.rb
class Place < ApplicationRecord
belongs_to :user
has_many :menus
end
Be careful not to confuse this singular and plural description, as naming conventions are important in Rails. It has (one) place for (one) user and (multiple) menus for (one) place.
belongs_to (belongs to) has_many (has a lot) ... It's easy to understand!
app/models/menu.rb
class Menu < ApplicationRecord
belongs_to :place
end
menu.rb looks like this.
For the time being, the linking between the tables is complete.
places_controller.rb
[1] pry(#<PlacesController>)> @place
=> #<Place:0x00007f9d1e88cc10
id: 3,
name: "hoge Coffee",
message: "The calm atmosphere at the nearest cafe from home is very nice.",
created_at: Thu, 18 Jun 2020 00:05:20 UTC +00:00,
updated_at: Thu, 18 Jun 2020 13:14:42 UTC +00:00,
user_id: 1>
[2] pry(#<PlacesController>)> params
=> <ActionController::Parameters {"controller"=>"places", "action"=>"show", "id"=>"3"} permitted: false>
I want to register the menu from views / places / show.html.erb
, so check the parameters.
This is the information of the cafe you want to register the menu this time.
ruby:places/show.html.erb
<%= link_to 'Register menu', new_menu_path(id: @place.id) %>
Go to the new action of menus_controller to register the menu.
If you do not pass an argument to the _path helper at this time, you will not be able to search for place with the new action of menus_controller.
menus_controller.rb
class MenusController < ApplicationController
def new
@menu = Menu.new
@place = Place.find_by(id: params[:id])
end
(Abbreviation)
Input form ↓
ruby:menus/new.html.erb
<%= form_with model:@menu, local: true do |f| %>
<h2>Register menu</h2>
<p>The name of the dish: <%= f.text_field :title %></p>
<p>Price : <%= f.text_field :price %></p>
<%= f.hidden_field :place_id, :value => @place.id %>
<%= f.submit 'sign up' %>
<% end %>
Since place_id is not something to enter, it will receive the value passed in hidden_field.
How to receive place_id in create action, but receive it in the input form when registering the menu.
menus_controller.rb
def create
#Receive the parameters received in the input form here
@menu = Menu.create(
title: menus_params[:title],
price: menus_params[:price],
place_id: menus_params[:place_id]
)
#I will check if I have received it properly here
binding.pry
end
(Omission)
private
def menus_params
params.require(:menu).permit(:title, :price, :place_id)
end
(Abbreviation)
I will fill out the form for confirmation. result···
python
[1] pry(#<MenusController>)> menus_params
=> <ActionController::Parameters {"title"=>"iced coffee", "price"=>"280", "place_id"=>"3"} permitted: true>
I was able to receive the place_id properly.
Now you can receive parameters that have a proper one-to-many relationship (menus for place).
<% @place.menus.each do |menu| %>
<p><%= menu.title %> <%= menu.price %></p>
<% end %>
The registered menu can be output like this.
[1] pry(#<PlacesController>)> @place.menus
(Abbreviation)
=> [#<Menu:0x00007ffda376a4c8
id: 37,
title: "Chocolate cake",
price: 250,
created_at: Thu, 18 Jun 2020 01:36:00 UTC +00:00,
updated_at: Thu, 18 Jun 2020 01:36:00 UTC +00:00,
place_id: 3>,
#<Menu:0x00007ffda3773eb0
id: 44,
title: "iced coffee",
price: 280,
created_at: Fri, 19 Jun 2020 00:24:50 UTC +00:00,
updated_at: Fri, 19 Jun 2020 00:24:50 UTC +00:00,
place_id: 3>]
Since it is linked by the association, you can check the menu registered with @ place.menus
.