无法在Rails中更新用户belongs_to关联

时间:2017-04-04 20:50:17

标签: ruby-on-rails activerecord associations

我有一个页面,其中用户(使用设计)通过复选框设置多个首选项,然后通过预定义数据的单选按钮设置。到目前为止,我让用户能够更新has_and_belongs_to_many关联,但我无法让我的belongs_to工作。

目前,我出现以下参数时出现此错误:

PG::ForeignKeyViolation: ERROR: insert or update on table "users" violates foreign key constraint

{"utf8"=>"✓",
 "_method"=>"patch",
 "user"=>{"sport_ids"=>["4"], "goal_ids"=>["6"], "moment_id"=>"moment_id", "workout_id"=>"workout_id"},
 "commit"=>"Save Changes",
 "id"=>"1"}

很明显,我没有通过身份证号码,但我不知道如何解决它。当我没有得到错误时没有任何反应。

这是我的文件

模型/ user.rb

class User < ApplicationRecord
  belongs_to :city
  belongs_to :workout
  belongs_to :fitness_level
  belongs_to :moment

  has_and_belongs_to_many :sports
  has_and_belongs_to_many :goals
  has_and_belongs_to_many :gyms
end

控制器/ users_controller.rb

class UsersController < ApplicationController

...

def edit
    @user = User.find(params[:id])
    @auth = current_user.id

    # To make sure you can't edit someone elses profile
    if @auth != @user.id
      redirect_to @user
    end

    @sports = Sport.all.order(name: :asc)
    @goals = Goal.all.order(name: :asc)
    @workouts = Workout.all.order(:name)
    @moments = Moment.all

  end

  def update
    @user = User.find(params[:id])

    if @user.update(user_params)
      redirect_to @user
    else
      render 'edit'
    end
  end

  def show
    @user = User.find(params[:id])
  end

  private

  def user_params
    params.require(:user).permit(sport_ids: [], goal_ids: [])
    params.require(:user).permit(:workout_id, :moment_id)
  end
end

的用户/ edit.html.erb

<%= simple_form_for @user do |f| %>


# The following two work
<% @sports.each do |sport| %>
    <%= check_box_tag "user[sport_ids][]", sport.id, form.object.sports.include?(sport) %>
    <%= sport.name %>
  <% end %>

<% @goals.each do |goal| %>
    <%= check_box_tag "user[goal_ids][]", goal.id, form.object.goal.include?(goal) %>
    <%= sport.name %>
  <% end %>

# the below doesn't work

<% @moments.each do |moment| %>

      <%= radio_button_tag 'user[moment_id]', :moment_id %>

    <h4><%= moment.name %></h4>

<% end %>  <!-- end moments-->

<% @workouts.each do |workout| %>

      <%= radio_button_tag 'user[workout_id]', :workout_id %>   

<% end %>  <!-- end workouts-->
<% end %> <! -- end form -->

我对使用标签的表单有一些重要的样式,因此需要保留。

编辑:在架构中添加用户表

create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.jsonb    "settings",               default: {}, null: false
    t.string   "first_name"
    t.string   "last_name"
    t.date     "date_of_birth"
    t.integer  "city_id"
    t.text     "bio"
    t.integer  "workout_id"
    t.integer  "fitness_level_id"
    t.integer  "moment_id"
    t.index ["city_id"], name: "index_users_on_city_id", using: :btree
    t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
    t.index ["fitness_level_id"], name: "index_users_on_fitness_level_id", using: :btree
    t.index ["moment_id"], name: "index_users_on_moment_id", using: :btree
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
    t.index ["settings"], name: "index_users_on_settings", using: :gin
    t.index ["workout_id"], name: "index_users_on_workout_id", using: :btree
  end

1 个答案:

答案 0 :(得分:1)

我很确定该行中的问题:

<%= radio_button_tag 'user[moment_id]', :moment_id %>

您不会将视图中的moment_id和workout_id传递给控制器​​的更新操作。

尝试将其更改为:

<% @moments.each do |moment| %>

    <%= radio_button_tag 'user[moment_id]', moment.id %>

    <h4><%= moment.name %></h4>

<% end %>  <!-- end moments-->

同样适合锻炼:

<% @workouts.each do |workout| %>

      <%= radio_button_tag 'user[workout_id]', workout.id %>  

<% end %>  <!-- end workouts-->

另外,为什么不通过一行允许的参数?像这样:

  def user_params
    params.require(:user).permit(:moment_id, :workout_id, sport_ids: [], goal_ids: [])
  end