如何正确创建和更新具有活动记录关联的帖子?
how to properly create and update posts with active record association?
所以我遇到了这个挑战,我无法弄清楚如何声明控制器以使其正常工作,我遇到了各种各样的错误,但我的主要问题是,现在的情况我无法保存新食谱或更新与下拉列表中使用的 recipe_type 模型关联的 'Tipo de Receita',请记住 recipe_type.name 将预先填充
那是进行编辑的edit.hmtl.erb
<%= form_for @recipe do |f| %>
<%= f.label :title, 'Título' %>
<%= f.text_field :title %>
<%= f.label :recipe_type, 'Tipo da Receita' %>
<%= collection_select(:recipe, :recipe_type_id, RecipeType.all, :id, :name) %>
<%= f.label :cuisine, 'Cozinha' %>
<%= f.text_field :cuisine %>
<%= f.label :difficulty, 'Dificuldade' %>
<%= f.text_field :difficulty %>
<%= f.label :cook_time, 'Tempo de Preparo' %>
<%= f.number_field :cook_time %>
<%= f.label :ingredients, 'Ingredientes' %>
<%= f.text_area :ingredients %>
<%= f.label :cook_method, 'Como Preparar' %>
<%= f.text_area :cook_method %>
<%= f.submit 'Enviar' %>
<% end %>
同样是注册新食谱的new.hmtl.erb
<%= form_for @recipe do |f| %>
<%= f.label :title, 'Título' %>
<%= f.text_field :title %>
<%= f.label :recipe_type, 'Tipo da Receita' %>
<%= collection_select(:recipe, :recipe_type_id, RecipeType.all, :id, :name) %>
<%= f.label :cuisine, 'Cozinha' %>
<%= f.text_field :cuisine %>
<%= f.label :difficulty, 'Dificuldade' %>
<%= f.text_field :difficulty %>
<%= f.label :cook_time, 'Tempo de Preparo' %>
<%= f.number_field :cook_time %>
<%= f.label :ingredients, 'Ingredientes' %>
<%= f.text_area :ingredients %>
<%= f.label :cook_method, 'Como Preparar' %>
<%= f.text_area :cook_method %>
<%= f.submit 'Enviar' %>
<% end %>
models/recipe_type 是下拉菜单中使用的
class RecipeType < ApplicationRecord
has_many :recipes
validates :name, presence: true
end
models/recipe 接收 recipe_type 模型
class Recipe < ApplicationRecord
belongs_to :recipe_type
validates :title, :cuisine, :difficulty, :cook_time,
:ingredients, :cook_method, presence: true
def cook_time_min
"#{cook_time} minutos"
end
end
recipes.controller.rb
class RecipesController < ApplicationController
def index
@recipes = Recipe.all
end
def show
@recipe = Recipe.find(params[:id])
end
def new
@recipe = Recipe.new
@recipe_type = RecipeType.all
end
def create
@recipe_type = RecipeType.all
@recipe = Recipe.new(recipe_params)
if @recipe.save
redirect_to @recipe
else
flash[:alert] = 'Você deve informar todos os dados da receita'
render :new
end
end
def edit
@recipe_type = RecipeType.all
@recipe = Recipe.find(params[:id])
@recipe_type = RecipeType.all
end
def update
@recipe = Recipe.find(params[:id])
if @recipe.update(recipe_params)
redirect_to @recipe
else
flash[:alert] = 'Você deve informar todos os dados da receita'
render :edit
end
end
private
def recipe_params
params.require(:recipe).permit(:title, :cuisine, :difficulty,
:cook_time, :ingredients, :cook_method, :name)
end
end
这就是架构
ActiveRecord::Schema.define(version: 2020_03_26_013134) do
create_table "recipe_types", force: :cascade do |t|
t.string "name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["recipe_id"], name: "index_recipe_types_on_recipe_id"
end
create_table "recipes", force: :cascade do |t|
t.string "title"
t.string "cuisine"
t.string "difficulty"
t.integer "cook_time"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "ingredients"
t.text "cook_method"
t.integer "recipe_type_id"
t.index ["recipe_type_id"], name: "index_recipes_on_recipe_type_id"
end
end
您需要在recipe_params
中添加recipe_type_id
:
def recipe_params
params.require(:recipe).permit(:recipe_type_id ...)
end
一个问题是您没有从表单生成器构建输入。您要使用:
<%= f.label :recipe_type_id, 'Tipo da Receita' # key has to match input for accessibility %>
<%= f.collection_select(:recipe_type_id, RecipeType.all, :id, :name) %>
collection_select
是一个简单的输入助手,它只会创建一个 select 标记,该标记未绑定到表单构建器,因此也不会绑定到您的模型实例。因此,如果记录无效或您正在更新现有记录,它将没有任何内容 selected.
f.collection_select
是表单生成器上的一种方法,将正确设置表单包装的模型实例中的 recipe_type_id
值。
您还需要允许白名单中的参数:
def recipe_params
params.require(:recipe)
.permit(
:title, :cuisine, :difficulty,
:cook_time, :ingredients, :cook_method,
:name, :recipe_type_id
)
end
所以我遇到了这个挑战,我无法弄清楚如何声明控制器以使其正常工作,我遇到了各种各样的错误,但我的主要问题是,现在的情况我无法保存新食谱或更新与下拉列表中使用的 recipe_type 模型关联的 'Tipo de Receita',请记住 recipe_type.name 将预先填充
那是进行编辑的edit.hmtl.erb
<%= form_for @recipe do |f| %>
<%= f.label :title, 'Título' %>
<%= f.text_field :title %>
<%= f.label :recipe_type, 'Tipo da Receita' %>
<%= collection_select(:recipe, :recipe_type_id, RecipeType.all, :id, :name) %>
<%= f.label :cuisine, 'Cozinha' %>
<%= f.text_field :cuisine %>
<%= f.label :difficulty, 'Dificuldade' %>
<%= f.text_field :difficulty %>
<%= f.label :cook_time, 'Tempo de Preparo' %>
<%= f.number_field :cook_time %>
<%= f.label :ingredients, 'Ingredientes' %>
<%= f.text_area :ingredients %>
<%= f.label :cook_method, 'Como Preparar' %>
<%= f.text_area :cook_method %>
<%= f.submit 'Enviar' %>
<% end %>
同样是注册新食谱的new.hmtl.erb
<%= form_for @recipe do |f| %>
<%= f.label :title, 'Título' %>
<%= f.text_field :title %>
<%= f.label :recipe_type, 'Tipo da Receita' %>
<%= collection_select(:recipe, :recipe_type_id, RecipeType.all, :id, :name) %>
<%= f.label :cuisine, 'Cozinha' %>
<%= f.text_field :cuisine %>
<%= f.label :difficulty, 'Dificuldade' %>
<%= f.text_field :difficulty %>
<%= f.label :cook_time, 'Tempo de Preparo' %>
<%= f.number_field :cook_time %>
<%= f.label :ingredients, 'Ingredientes' %>
<%= f.text_area :ingredients %>
<%= f.label :cook_method, 'Como Preparar' %>
<%= f.text_area :cook_method %>
<%= f.submit 'Enviar' %>
<% end %>
models/recipe_type 是下拉菜单中使用的
class RecipeType < ApplicationRecord
has_many :recipes
validates :name, presence: true
end
models/recipe 接收 recipe_type 模型
class Recipe < ApplicationRecord
belongs_to :recipe_type
validates :title, :cuisine, :difficulty, :cook_time,
:ingredients, :cook_method, presence: true
def cook_time_min
"#{cook_time} minutos"
end
end
recipes.controller.rb
class RecipesController < ApplicationController
def index
@recipes = Recipe.all
end
def show
@recipe = Recipe.find(params[:id])
end
def new
@recipe = Recipe.new
@recipe_type = RecipeType.all
end
def create
@recipe_type = RecipeType.all
@recipe = Recipe.new(recipe_params)
if @recipe.save
redirect_to @recipe
else
flash[:alert] = 'Você deve informar todos os dados da receita'
render :new
end
end
def edit
@recipe_type = RecipeType.all
@recipe = Recipe.find(params[:id])
@recipe_type = RecipeType.all
end
def update
@recipe = Recipe.find(params[:id])
if @recipe.update(recipe_params)
redirect_to @recipe
else
flash[:alert] = 'Você deve informar todos os dados da receita'
render :edit
end
end
private
def recipe_params
params.require(:recipe).permit(:title, :cuisine, :difficulty,
:cook_time, :ingredients, :cook_method, :name)
end
end
这就是架构
ActiveRecord::Schema.define(version: 2020_03_26_013134) do
create_table "recipe_types", force: :cascade do |t|
t.string "name"
t.integer "recipe_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["recipe_id"], name: "index_recipe_types_on_recipe_id"
end
create_table "recipes", force: :cascade do |t|
t.string "title"
t.string "cuisine"
t.string "difficulty"
t.integer "cook_time"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "ingredients"
t.text "cook_method"
t.integer "recipe_type_id"
t.index ["recipe_type_id"], name: "index_recipes_on_recipe_type_id"
end
end
您需要在recipe_params
中添加recipe_type_id
:
def recipe_params
params.require(:recipe).permit(:recipe_type_id ...)
end
一个问题是您没有从表单生成器构建输入。您要使用:
<%= f.label :recipe_type_id, 'Tipo da Receita' # key has to match input for accessibility %>
<%= f.collection_select(:recipe_type_id, RecipeType.all, :id, :name) %>
collection_select
是一个简单的输入助手,它只会创建一个 select 标记,该标记未绑定到表单构建器,因此也不会绑定到您的模型实例。因此,如果记录无效或您正在更新现有记录,它将没有任何内容 selected.
f.collection_select
是表单生成器上的一种方法,将正确设置表单包装的模型实例中的 recipe_type_id
值。
您还需要允许白名单中的参数:
def recipe_params
params.require(:recipe)
.permit(
:title, :cuisine, :difficulty,
:cook_time, :ingredients, :cook_method,
:name, :recipe_type_id
)
end