I have 6 modules (1. ingredients; 2. restaurants; 3. sandwich_ingredients; 4. sandwiches; 5. stocks; 6. users) and the user should be able to create/personalise a sandwich using the ingredients of that specific restaurant. Therefore, I would like to create a form on the show.html.erb of the restaurant so that the user can pick up several ingredients and create their own sandwich.
I feel comfortable working with 3 modules in a many-to-many relationship but with 6 tables I just get confused and lost.
I tried form_for, form_tag, collection_check_boxes. When I used to work with a smaller project, I had no issues but now I'm not sure what approach should I take. I tried to create the form on the user show page first and then on the sandwich show page but it didn't seem quite right.
This is the code from the restaurant show.html.erb page:
<ul>
<%= form_tag('/restaurants/create_sandwich') do %>
<%= label_tag 'Ingredients' %>
<li><%= collection_check_boxes(:ingredient, :id, @restaurant.ingredients, :id, :name) %></li>
<%= submit_tag 'Create' %>
<% end %>
</ul>
The restaurants_controller.rb (messed up):
class RestaurantsController < ApplicationController
def index
@restaurants = Restaurant.all
end
def show
@restaurant = Restaurant.find(params[:id])
@user = User.new
@sandwich = Sandwich.new
end
def new
@sandwich = Sandwich.new
# res = Restaurant.find(params[:id])
# @restaurant_ingredients = res.ingredients
end
def select_ingredients
# byebug
#
# @restaurant_ingredients = Restaurant.find(params[:id]).ingredients
# byebug
# @restaurant_ingredients = res.ingredients
# @ingredients = Ingredient.all
end
def create_sandwich
# byebug
@user = User.find_or_create_by({name: params[:user_name]})
@sandwich = Sandwich.new({name: params[:recipe_name], user_id: @user.id})
@sandwich.sandwich_ingredient_ids = params[:ingredients]
if @sandwich.save
redirect_to sandwich_path(@sandwich)
else
render :new
end
end
def edit
#code
end
def update
#code
end
def delete
#code
end
end
If it can help, these are the routes:
Rails.application.routes.draw do
# get '/restaurants/:id', to: 'restaurants#create_sandwich'
post '/restaurants/create_sandwich', to: 'restaurants#create_sandwich'
resources :stocks
resources :restaurants
resources :sandwich_ingredients
resources :ingredients
resources :sandwiches
resources :users
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
and this is my schema:
ActiveRecord::Schema.define(version: 2019_04_15_174308) do
create_table "ingredients", force: :cascade do |t|
t.string "name"
t.integer "quantity"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "restaurants", force: :cascade do |t|
t.string "name"
t.string "location"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "sandwich_ingredients", force: :cascade do |t|
t.integer "sandwich_id"
t.integer "ingredient_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "sandwiches", force: :cascade do |t|
t.string "name"
t.integer "user_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "stocks", force: :cascade do |t|
t.integer "restaurant_id"
t.integer "ingredient_id"
t.integer "count"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "surname"
t.string "email"
t.string "phone_number"
t.integer "age"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
What I'm trying to achieve is a form that would create the association "SandwichIngredient" and to do so, the "User" and the "Sandwich" but at this point I feel just lost.
答案 0 :(得分:1)
Lots of areas to comment on here, and the question is quite vague but I'll give some tips
Your 'new' action on your restaurant controller should be for a new restaurant, not a new sandwich.
Your 'new sandwich' form should probably be directing to the create action on your sandwiches controller. You're trying to do too much on the restaurants controller.
If your ingredients belong to a restaurant, they need a restaurant_id field
You probably don't want to create a new user each time you create a sandwich, perhaps you want to add devise or a similar user management gem to your project and have them sign in, and assign the sandwich to the current user, or have a drop down select of the users in the system as part of the sandwich form
As a general tip, I would completely ignore your stocks model for now, focus on getting sandwiches working first.
Not super related but would be good to have either one 'name' field for a user or 'first_name' and 'last_name' to avoid confusion
You may need to add a hidden field in the form to contain the restaurant_id to be able to pass this value through when you submit the form
Make sure you have a field on the sandwich form for the name of the sandwich
Feel free to post a link to this project on github or similar if you need further help.