Rails, как обновить колонку после сохранения? - PullRequest
14 голосов
/ 25 апреля 2011

Я хочу создать метод after_save для моего действия по ставке.Было бы разделить рейтинг_счета / рейтинги и обновить рейтинг столбца.

class KonkurrancersController < ApplicationController
  def rate
    @konkurrancer = Konkurrancer.find(params[:id])
    @container = "Konkurrancer"+@konkurrancer.id.to_s

    @konkurrancer.rating_score += params[:vind][:rating].to_i
    @konkurrancer.ratings += 1
    @konkurrancer.save

    respond_to do |format|
      format.js
    end
  end
end

Это моя модель:

class Konkurrancer < ActiveRecord::Base
  after_save :do_foobar

  private
    def do_foobar

      rating_score = self.rating_score
      ratings = self.ratings
      rating = (rating_score/ratings)
      self.update_attributes(:rating => rating)

    end
end

Мой журнал рельсов:

Started POST "/konkurrancers/rate/46" for 127.0.0.1 at 2011-04-26 23:40:56 +0200

  Processing by KonkurrancersController#rate as */*
  Parameters: {"utf8"=>"Ô£ô", "authenticity_token"=>"MACFM37hX4S6XA9vryn7gtfl21P
vcaPBSiKDI8mfurg=", "vind"=>{"rating"=>"4"}, "id"=>"46"}
  ←[1m←[36mKonkurrancer Load (1.0ms)←[0m  ←[1mSELECT `konkurrancers`.* FROM `kon
kurrancers`←[0m
  ←[1m←[35mCACHE (0.0ms)←[0m  SELECT `konkurrancers`.* FROM `konkurrancers`
  ←[1m←[36mCACHE (0.0ms)←[0m  ←[1mSELECT `konkurrancers`.* FROM `konkurrancers`←
[0m
  ←[1m←[35mKonkurrancer Load (1.0ms)←[0m  SELECT `konkurrancers`.* FROM `konkurr
ancers` WHERE (`konkurrancers`.`cached_slug` = '46') LIMIT 1
  ←[1m←[36mSQL (2.0ms)←[0m  ←[1mSELECT sluggable_id FROM slugs WHERE ((slugs.slu
ggable_type = 'Konkurrancer' AND slugs.name = '46' AND slugs.sequence = 1))←[0m
  ←[1m←[35mKonkurrancer Load (1.0ms)←[0m  SELECT `konkurrancers`.* FROM `konkurr
ancers` WHERE (`konkurrancers`.`id` = 46) LIMIT 1
  ←[1m←[36mSQL (0.0ms)←[0m  ←[1mBEGIN←[0m
  ←[1m←[35mLink Load (1.0ms)←[0m  SELECT `links`.* FROM `links` WHERE (`links`.k
onkurrancer_id = 46) LIMIT 1
  ←[1m←[36mSQL (0.0ms)←[0m  ←[1mROLLBACK←[0m
Rendered konkurrancers/_rating.html.erb (1.0ms)
Rendered konkurrancers/rate.js.erb (22.0ms)
Completed 200 OK in 606ms (Views: 286.0ms | ActiveRecord: 6.0ms)

Как мне создать это?

Ответы [ 5 ]

69 голосов
/ 28 февраля 2014

Любой update_attribute в обратном вызове after_save вызовет рекурсию в Rails3 +. Что нужно сделать, это:

after_save :updater
# Awesome Ruby code
# ...
# ...

private

  def updater
    self.update_column(:column_name, new_value) # This will skip validation gracefully.
  end
11 голосов
/ 25 апреля 2011

что вы хотите, это обратный вызов. Вы можете создать обратный вызов after_save для вашей модели Konkurrancer, который срабатывает после вызова метода save () для этой модели.

Например:

class Konkurrancer < ActiveRecord::Base
  after_save :do_foobar

  private
    def do_foobar

      rating_score = self.rating_score
      ratings = self.ratings
      rating = (rating_score/ratings)
      self.update_attributes(:ratings => rating)

    end
end

[РЕДАКТИРОВАТЬ] Вы должны использовать self , так как редактируемая вами модель - это сама модель. Проверьте это и примените необходимую логику / реализацию.

Посмотрите эту инструкцию для получения дополнительной информации.

Надеюсь, это поможет!

9 голосов
/ 10 мая 2014

Не уверен, почему люди голосуют против неправильного ответа и голосуют против правильного ответа.

Закелфасси прав, а Кристиан Фаззини неправ для Рельсов 3 и выше. Если вы выполняете #update_attributes в обратном вызове сохранения, вы переходите к бесконечной рекурсии. Вы хотите сделать #update_column согласно его примеру.

Попробуйте сами, и вы увидите.

0 голосов
/ 25 апреля 2011
0 голосов
/ 25 апреля 2011
  @konkurrancer.update_attributes :ratings=>'updated value'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...