Метод обновления не обновляет объект пользователя, нет проблем с params или form_for? - PullRequest
0 голосов
/ 03 марта 2019

Я изучаю рельсы, создавая веб-сайт форума, и у меня есть две основные модели: пользователи и темы.Они имеют отношение многие ко многим, используя has_many_through в качестве третьей модели, subscribed_topic.

В пользовательском шоу у меня есть следующее 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)

Я не понимаю, почему прохождение этого набора тем вызовет проверку пароля и пройдет проверку имени и электронной почты, но для этого я попрошуновый вопрос

1 Ответ

0 голосов
/ 03 марта 2019

ваши параметры missiong 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 } %>
...