【发布时间】:2015-09-21 04:44:03
【问题描述】:
我有一个跟踪锻炼和锻炼的应用程序,但在控制器中关联它们时遇到问题。我想将一系列练习与给定的个人锻炼联系起来。我遇到的问题是控制器的创建操作。我已经包含了其他文件作为上下文。
我还没有看到任何通过与模型的一个以上实例建立关联的示例。在 Rails 控制台中,我可以轻松地将它们关联起来
ex = Exercise.all.last
workout = Workout.all.last
workout.exercises.push(ex)
workout.exercises#列出所有练习
这是如何在控制器中完成的?
我查阅了 Rails Getting Started Guides,但他们的讨论并未讨论 HABT 关系。我咨询了 RailsCasts,但很多信息来自 Rails 4 之前的信息。我还搜索了其他 Stack 问题,但未能找到可能是一个非常简单的例子来说明它是如何工作的。
架构:
create_table "exercises", force: :cascade do |t|
t.string "name"
t.integer "reps"
t.integer "sets"
t.string "primary"
t.string "other"
end
create_table "exercises_workouts", force: :cascade do |t|
t.integer "exercise_id"
t.integer "workout_id"
end
create_table "workouts", force: :cascade do |t|
t.datetime "created_at"
t.datetime "updated_at"
t.string "category"
end
型号:
class Exercise < ActiveRecord::Base
has_and_belongs_to_many :workouts
end
class Workout < ActiveRecord::Base
has_and_belongs_to_many :exercises
end
查看:
<%= form_for [@workout] do |f| %>
...
<% if @exercises.any? %>
<% @exercises.each do |exercise| %>
<%= hidden_field_tag "workout[exercise_ids][]", nil %>
<%= check_box_tag "workout[exercise_ids][]", exercise.id,
@workout.exercise_ids.include?(exercise.id), id: dom_id(exercise) %>
<%= label_tag dom_id(exercise), exercise.name %><br>
<% end %>
<% end %>
...
控制器:
def new
@workout = Workout.new
get_exercises
end
def create
@workout = Workout.new(workout_params)
@workout.exercises.push(params[:exercise_ids])
if @workout.save
flash[:success] = "Successfully created workout!"
redirect_to @workout
else
render 'new'
end
end
...
def workout_params
params.require(:workout).permit(:category)
end
这个错误是因为
ActiveRecord::AssociationTypeMismatch in WorkoutsController#create Exercise(#70125693469000) expected, got NilClass(#70125638586940)
尝试 2
我现在避免了这个错误,但它并没有建立关系。我试过了:
@workout.exercise_ids.push(params[:exercise_ids])
尝试 3
我现在看到参数正在传入,我已经尝试过:
@workout.exercises.push(params[:workout][:exercise_ids])
尝试 4
再次尝试,但没有保存
@workout = Workout.new(workout_params)
private
def workout_params
params.require(:workout).permit(:category, :exercise_id)
end
尝试 5
我再次尝试明确说明我想要传递的练习。然而,这产生了使视图无法识别@exercises 变量的奇怪影响。不知道为什么会这样。
@workout.exercises.build(params[:exercise_ids])
如果有任何建议,我将不胜感激。谢谢
尝试 6
我认为因为在控制台中我可以推动练习,所以我可以在控制器中做同样的事情。没有骰子。
@workout.exercises.push(params[:exercise_ids])
尝试 7
在查看ruby on rails - how to make relationship works in route, controller, view ? has_many, belongs_to 之后,我尝试通过以下方式调整我的代码:
@workout = Workout.new
@workout = @workout.exercises.build(params[:workout_params])
...
def workout_params
params.require(:workout).permit(:category, :exercise_ids)
end
但是,这会在视图层中引发错误:undefined methodcategory' for #`。
尝试 8
我试过了:
@workout = Workout.new.exercises.build(params[:workout_params])
【问题讨论】:
-
我只是在掩饰您的代码,但我认为问题/问题可能出在您的模型上。您使用 2 个 HABTM 关系,但我可能是错的......只是一个建议。
-
为什么会有问题?我是 Rails 新手,所以我遵循指南的建议:guides.rubyonrails.org/…
-
第一步:查看日志并找出您在创建消息中获得的参数。了解他们。然后重新检查您的代码,包括锻炼参数方法。我可以发现至少两个错误。
-
我用过调试器,练习参数是通过
params[:workout][:exercise_ids]访问的。我的问题是我不知道加入这两项的 Rails 控制器关联语法。 -
我想我理解这个想法,但我不知道语法。我知道我必须从表单传递的参数中获取这些练习 ID。我必须在我的锻炼参数方法中将它们列入白名单,然后我必须将它们推送到锻炼容器中进行锻炼。我只是不知道这是如何发生的语法。
标签: ruby-on-rails ruby ruby-on-rails-4