I am trying to create recipe app that users can take. Part of the app is an admin users getting to create the recipes and instructions.
There is a User model/table with all the users. This has a controller.
There is also a recipe table with all the recipes created.
Finally there is an instructions table that are each associated with a recipe
What I am trying to make happen is the admin user visits a page to create a recipe. This page also has a list of existing recipes. The user can click on one of the recipes which brings the user to an edit page where they can edit the instructions for the recipe. The edit page shows a list of instructions. You can also add an instruction.
The problem is the form_with
on the recipe create page is showing an error:
undefined method `recipes_path'
I don't have a recipe controller. The only controller is the user controller. Inside this controller I have defined an admin
action a create_recipe
action an edit_recipe
action and an update_recipe
action:
def admin
@recipe = Recipe.new(
recipe_params
)
@Recipes = Recipe.all
end
def create_recipe
if @recipe.save
redirect_to root_url
else
render 'new'
end
end
def edit_recipe
@recipe = Recipe.find(params[:id])
@recipe_instructions = RecipeInstructions.where(recipe_id: @recipe.id)
end
def update_recipe
@recipe = Recipe.find(params[:id])
@recipe_instructions = RecipeInstructions.where(recipe_id: @recipe.id)
if @recipe.update(recipe_params)
redirect_to root_url
else
render :edit
end
The routes look like this:
get 'admin', to: 'users#admin', as: :admin
get 'recipes/:id/edit', to: 'users#edit_recipe', as: :edit_recipe_instructions
post 'recipes/:id/update', to: 'users#update_recipe', as: :update_recipe_instructions
Here is the view of the recipe page:
<div id = "signup-form-container">
<%= form_with model: @recipe do |newRecipe| %>
<h3 class="signup-form-heds"> <%= newRecipe.label :recipe_name, "Recipe name" %></h3>
<%= newRecipe.text_field :recipe_name, class: "form-inputs form-text-inputs"%>
<%= newRecipe.submit "SAVE", class: "btns submit-btns", id: "signup-submit-btn" %>
<% end %>
</div>
Though I get the error. I'm also worried a similar error will happen with the instructions page because I'm using a similar form, but with multiple models.
<%= form_with model: [@recipe, @recipe_instructions], url: update_recipe_instructions_path(@recipe) do |newRecipe| %>
<%= newRecipe.fields_for :recipe do |recipeData| %>
<h3 class="signup-form-heds"> <%= recipeData.label :recipe_name, "Recipe name" %></h3>
<%= recipeData.text_field :recipe_name, class: "form-inputs form-text-inputs"%>
<% end %>
<%= newRecipe.fields_for :recipe_instructions do |recipeInstructions| %>
<h3 class="signup-form-heds"> <%= recipeInstructions.label :instruction, "Instruction" %></h3>
<%= recipeInstructions.text_field :recipe_instructions , class: "form-inputs form-text-inputs"%>
<% end %>
<%= newRecipe.submit "SAVE", class: "btns submit-btns", id: "signup-submit-btn" %>
<% end %>
</div>
I'm thinking it's the fact that the models don't have controllers that's causing the issue?
<div id = "signup-form-container">
<%= form_with model: @recipe do |newRecipe| %>
<h3 class="signup-form-heds"> <%= newRecipe.label :recipe_name, "Recipe name" %></h3>
<%= newRecipe.text_field :recipe_name, class: "form-inputs form-text-inputs"%>
<%= newRecipe.submit "SAVE", class: "btns submit-btns", id: "signup-submit-btn" %>
<% end %>
</div>
When you pass model: @recipe in the form, the resulted form action is '/recipes', that is the path to create a new recipe, but you don't have a path to create a recipe, or at least that's what I think, you're showing only three routes, one route to the admin, one to show the edit form and one to update the recipe, this last must be a patch or put route instead of post.
Create a new route like:
post '/recipes', to: 'users#create' # this must be a post route because you will create a new recipe
Despite this could resolve your problem, this isn't the correct way to do what you are doing.
In the Users controller you are creating a recipe, this is incorrect. In your project, you could have two controllers, one for the Users and one for the Recipes.
Also, you could create the routes with:
resources :users
resources :recipes
This a quickly way to create the 7 basic routes index, show, new, edit, create, update and destroy. See Rails routing from the outside
If you have two different tables, one for recipes and one for instructions, in your Recipe model must have:
has_many :instructions
and in your Instructions model you must have:
belongs_to :recipe
Of course, you also must have the required Foreign Keys to make the relation between this two tables. And then, when you create a new recipe could do something like:
@recipe.instructions << params[:instructions]