我有一个页面,其中用户(使用设计)通过复选框设置多个首选项,然后通过预定义数据的单选按钮设置。到目前为止,我让用户能够更新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"}
很明显,我没有通过身份证号码,但我不知道如何解决它。当我没有得到错误时没有任何反应。
这是我的文件
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
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
<%= 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
答案 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