【问题标题】:Update method not updating user object, no issue with params or form_for?更新方法不更新用户对象,params 或 form_for 没有问题?
【发布时间】:2019-07-25 03:31:03
【问题描述】:

我通过建立一个论坛网站来学习 Rails,并且有两个主要模型:用户和主题。他们通过第三个模型subscribed_topic 使用has_many_through 建立多对多关系。

在用户展示中,我有以下form_for,以允许用户通过复选框选择主题。我正在尝试使用它将所选主题保存给特定用户。

<%= form_for @user do |f| %> 
<%= f.collection_check_boxes(:topic_ids, 
Topic.all.sample(50).each, :id, :topic_name) %> 
<%= f.submit %>
<% end %>

我的用户控制器中有这个更新方法,在提交表单时调用。

def update
  @user = User.find(params[:id])
  if @user.update_attributes(user_params)
    flash[:success] = "Success!"
  else
    flash[:warning] = "Failed!"
  end
end

这些是我的用户参数:

def user_params
  params.require(:user).permit(
  :name, :email, :password,
  :password_confirmation, topic_ids: [])
end

这些是供参考的各自架构:

create_table "subscribed_topics", force: :cascade do |t|
  t.integer  "user_id"
  t.integer  "topic_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "topics", force: :cascade do |t|
  t.string   "topic_name"
  t.integer  "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["user_id"], name: "index_topics_on_user_id"
end

create_table "users", force: :cascade do |t|
  t.string   "name"
  t.string   "email"
  t.datetime "created_at",      null: false
  t.datetime "updated_at",      null: false
  t.string   "password_digest"
  t.index ["email"], name: "index_users_on_email", unique: true
end

编辑:我将topic_ids: [] 添加到我的用户参数中,但更新没有通过。

日志显示:

User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
 (0.1ms)  begin transaction
Topic Load (0.2ms)  SELECT "topics".* FROM "topics" WHERE "topics"."id" = 41 ORDER BY "topics"."created_at" DESC
Topic Load (0.2ms)  SELECT "topics".* FROM "topics" INNER JOIN "subscribed_topics" ON "topics"."id" = "subscribed_topics".
"topic_id" WHERE "subscribed_topics"."user_id" = ? ORDER BY "topics"."created_at" DESC  [["user_id", 1]]
SQL (0.4ms)  INSERT INTO "subscribed_topics" ("user_id", "topic_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["user_id", 1], ["topic_id", 41], ["created_at", "2019-03-03 19:49:43.212973"], ["updated_at", "2019-03-03 19:49:43.212973"]]
User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND ("users"."id" != ?) LIMIT ?  [["email", "user.email@gmail.com"], ["id", 1], ["LIMIT", 1]]

(0.3ms)  rollback transaction

编辑:用户和主题模型验证

用户中的验证是:

validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 }

主题中唯一的验证是:

validates :topic_name, presence: true, length: {maximum: 255}

编辑:特定的验证错误来自用户模型

Validation failed: Password can't be blank, Password is too short (minimum is 6 characters)

我不明白为什么传递这个主题集合会触发密码验证并传递姓名和电子邮件验证,但为此我会问一个新问题。

【问题讨论】:

  • 使用 bang 方法 @user.update!(user_params) 在日志中明确查看验证错误
  • 谢谢@Vasilisa!这帮助我找到了确切的问题!
  • 很高兴为您提供帮助:)

标签: ruby-on-rails ruby-on-rails-5 has-many-through


【解决方案1】:

你的参数任务 topic_ids 你可以像下面的示例代码一样添加它

def user_params
  params.require(:user).permit(
  :name, :email, :password,
  :password_confirmation, topic_ids: [])
end

编辑:

我认为您的更新控制器已经正确,用户选择主题的其他选择可以使用 collection_select

 <%= f.collection_select :topic_ids, Topic.all.sample(50), :id, :topic_name, {}, { multiple: true } %>

【讨论】:

  • 嗯,这完全有道理。但是,由于某种原因,更新仍然没有通过。 @widjajayd
  • 我更改为 collection_select 以查看它是否有所作为,但更新仍未通过。我发布了日志,有什么想法吗?
  • 日志底部,你看到回滚事务意味着你更新的数据无法保存,你可以先检查你的验证规则,以及用户和主题之间的表关系
  • 我将这两个模型的验证添加到我的帖子中,因为我不确定我应该寻找什么。我没有看到任何限制性的东西。我错过了验证吗?我不确定我知道你所说的表关系是什么意思;关联是 has_many_through。
猜你喜欢
  • 2015-11-15
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-30
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
相关资源
最近更新 更多