Rails: обновить оценку пользователя после того, как он написал комментарий

#ruby-on-rails #comments

#ruby-on-rails #Комментарии

Вопрос:

я действительно новичок в Rails, и мне интересно, как можно сделать следующее:

После того, как пользователь написал комментарий к sin ( = статье), автор ( = пользователь) должен получить 20 баллов (например), добавленных к его оценке (= user.score). оценка — это столбец в моей таблице пользователей.

Мои модели выглядят следующим образом:

 class User < ActiveRecord::Base
  has_many :comments, :dependent => :destroy
  has_many :absolutions, :dependent => :destroy
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :sin
end

class Sin < ActiveRecord::Base
  has_many :comments, :dependent => :destroy
end
  

Мой контроллер комментариев выглядит следующим образом:

 class CommentsController < ApplicationController

  def new
    @comment = Comment.new
  end

  def create
    @sin = Sin.find(params[:sin_id])
    @comment = current_user.comments.build(params[:comment])
    @comment.sin_id = @sin.id
    if @comment.save
      flash[:success] = "Comment created!"
      redirect_to sin_path(@sin)
    else
      flash[:error] = "Comment was not created."
      redirect_to sin_path(@sin)
    end
  end

end
  

Потратив несколько часов на то, чтобы разобраться с этим самостоятельно, я немного запутался. После создания комментария я хотел бы изменить конкретное значение связанного объекта User.

Какой был бы лучший способ сделать это?

Спасибо за вашу помощь!

Ответ №1:

Вы могли бы просто добавить его после сохранения :

 if @comment.save
  flash[:success] = "Comment created!"
  current_user.score  = 20
  current_user.save
  redirect_to sin_path(@sin)
else
  

НО всегда лучше делать это в вашей модели. Итак, я бы создал метод экземпляра add_score в вашей пользовательской модели и обновил оценку там. Тогда я бы просто вызвал этот метод в контроллере, в том же месте.

Комментарии:

1. Спасибо за вашу помощь! Я попробовал ваш совет и сначала вставил его в контроллер, но получаю следующую ошибку: неопределенный метод `score’ для #<User: 0x007ff48818cc50>.

2. Это означает, что у вас нет атрибута оценки в вашей пользовательской модели. Добавьте его, пожалуйста 🙂

3. О, моя ошибка, я переименовал этот столбец, прежде чем поместить сюда код. Теперь комментарий создан (с помощью предложенного вами кода в контроллере комментариев), НО значение user.score не обновляется.

4. он не обновляется, потому что у вас либо есть attr_accessible, либо проверки завершаются неудачей. Вы можете использовать update_attribute для сохранения значения.

5. Большое спасибо за вашу помощь. ТЕПЕРЬ это работает. Я использую следующие строки (монеты = оценка): coins_new = current_user.coins 20 current_user.update_attribute(:монеты, coins_new) Еще раз большое спасибо за вашу помощь!

Ответ №2:

Определите after_save обратный вызов в вашей модели комментариев:

 class Comment < ActiveRecord::Base
  [...]

  after_save :add_score

  private

  def add_score
    self.user.score  = 20
    self.user.save
  end
end
  

Комментарии:

1. Спасибо за вашу помощь! Однако, когда я вставляю эти строки, я получаю ошибку: неопределенный метод `score’ для «#<User:0x000000039f9ae0>»:User.

2. Это предполагало, что у вас есть атрибут score в вашей User модели, означающий столбец в вашей user таблице в базе данных. Если у вас этого нет, вам придется добавить его через миграцию, и тогда это сработает.

3. Еще одна вещь, которую я собирался добавить сюда: after_save метод будет запускаться каждый раз, когда комментарий сохраняется в базе данных, даже когда вы его обновляете. Я предполагаю, что вы хотите увеличить оценку пользователя только тогда, когда он / она создает новый комментарий, не обязательно при его обновлении. Сказав это, вы, вероятно, захотите иметь after_create обратный вызов вместо after_save .

Ответ №3:

Вы могли бы использовать обратный вызов after_create в вашей модели комментариев, который вносит изменения в соответствующего пользователя?

Такого рода логика не относится к контроллеру.