【问题标题】:Associating multiple objects in Rails controller在 Rails 控制器中关联多个对象
【发布时间】: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


【解决方案1】:

试试这个:

Workout.create!(workout_params)

workout_params 应该包含这个:

def workout_params
  params.require(:workout).permit(:category, :exercise_ids => [])
end

您还可以在此处查看 HABTM 文档:http://guides.rubyonrails.org/association_basics.html#has-and-belongs-to-many-association-reference

【讨论】:

  • 对我来说仍然没有通过。表格通过了,但如果我检查锻炼,它里面没有任何练习。我知道表单正在检索它们,但它们没有关联。
  • 在 2015-09-20 13:35:29 -0700 开始 POST "/workouts" for ::1 由 WorkoutsController#create 作为 HTML 参数处理:{"utf8"=>"✓", "authenticity_token"=>"tj9+/7iXOfgtxdmVtBq6EskuM3g4smzWPKl6hABisp1mC8I8Q1XQMNhrShlzwUH2qAxv9Rs2ceoE08UFVnMCEQ==", "workout"=>{"category"=>"Fitness", "exercise_ids"=>["}", "2", "" "commit"=>"Create Workout"} [1m[36mUser Load (0.1ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1[0m [["id", 1]] 不允许的参数:executive_ids
  • 我不能全部列出,但是即使我在def workout_params params.require(:workout).permit(:category, :exercise_ids) end 中将它列入白名单,executive_ids 也是一个不允许的参数
  • 嗯,我使用控制台仔细检查。我运行了这个:Workout.all.last.exercises.count,它返回 0。
  • 哦,我想我理解了这个问题,请查看我更新的答案。
猜你喜欢
  • 2014-02-13
  • 2017-04-19
  • 1970-01-01
  • 2012-06-27
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多