#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 в вашей модели комментариев, который вносит изменения в соответствующего пользователя?
Такого рода логика не относится к контроллеру.