Wie implementieren Sie einen Zähler -Cache in Schienen?
-
23-10-2019 - |
Frage
Ich habe einen Post -Controller und einen Kommentarcontroller. Post hat viele Kommentare und Kommentare gehören zum Post. Der Mitarbeiter wird mit der Option counter_cache eingerichtet, die als solche eingeschaltet wurde:
#Inside post.rb
has_many :comments
#Inside comment.rb
belongs_to :post, :counter_cache => true
Ich habe ein comments_count
Spalte in meinem posts
Tabelle, die als solche standardmäßig auf Null gesetzt wird:
add_column :posts, :comments_count, :integer, :default => 0
In dem create
Aktion meines Kommentarcontrollers, ich habe den folgenden Code:
def create
@posts = Post.find(params[:post_id])
@comment = @post.comments.build(params[:comment])
if @comment.save
redirect_to root
else
render :action => 'new'
end
end
Mein Problem: Wann @comment.save
Es wird angerufen, ich erhalte den folgenden Fehler:
ArgumentError in CommentsController#create
wrong number of arguments (2 for 0)
Entfernen :counter_cache => true
Aus Kommentar.rb löst das Problem vollständig, daher gehe ich davon aus, dass es die Ursache für diesen vagen Fehler ist. Was vermisse ich hier? Wie kann ich meinen Kommentar speichern und trotzdem die Schienen für meinen Beitrag um meinen counter_cache kümmern?
Vielen Dank!
UPDATE - Anwendungsverfolgung beigefügt:
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:987:in `update_all'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:987:in `update_counters_without_lock'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/locking/optimistic.rb:176:in `update_counters'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:1006:in `increment_counter'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations.rb:1367:in `belongs_to_counter_cache_after_create_for_feed_entry'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:178:in `send'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:178:in `evaluate_method'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:166:in `call'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:93:in `run'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:92:in `each'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:92:in `send'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:92:in `run'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:276:in `run_callbacks'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/callbacks.rb:344:in `callback'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/callbacks.rb:267:in `create'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2915:in `create_or_update_without_callbacks'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/callbacks.rb:250:in `create_or_update'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2573:in `save_without_validation'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/validations.rb:1090:in `save_without_dirty'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/dirty.rb:79:in `save_without_transactions'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:229:in `send'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:229:in `with_transaction_returning_status'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:182:in `transaction'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:228:in `with_transaction_returning_status'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:196:in `save'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:196:in `save'
/Users/yuval/Sites/rails/blog/app/controllers/comments_controller.rb:6:in `create'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:1331:in `send'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:1331:in `perform_action_without_filters'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:617:in `call_filters'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/rescue.rb:160:in `perform_action_without_flash'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/flash.rb:151:in `perform_action'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:532:in `send'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:532:in `process_without_filters'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:606:in `process'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:391:in `process'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:386:in `call'
/Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/routing/route_set.rb:438:in `call'
Beachten Sie, dass die einzige Linie, die nicht direkt mit dem Rails -Framework ausführen muss, lautet:
/Users/yuval/Sites/rails/blog/app/controllers/comments_controller.rb:6:in `create'
Zeile 6 ist die folgende:
if @comment.save
Bearbeiten 2: das @posts
/@post
Ist ein Tippfehler an meinem Ende, wenn ein vereinfachtes Beispiel für Stackoverflow geschrieben wird. Meine tatsächliche Anwendung hat keinen Fehler.
Inspizieren @comment
, Es scheint völlig gültig zu sein - es kehrt genau zurück, was ich erwarte - eine neue Instanz des Kommentars mit den Informationen, die ich an sie übergeben habe build
. Es bläst nur auf, wenn die save
Methode wird darauf aufgerufen.
Vielen Dank für alle Vorschläge bisher. Irgendwelche anderen Ideen?
Lösung
Ich habe eine Beispiel -Rails -App mit Ihrem Code durchlaufen und alles hat für mich gut funktioniert.
Ich würde vorschlagen, ein bisschen mehr zu debuggen, wie Hurikhan77 vorschlägt, und festzustellen, ob es sich nur um das Problem @posts / @Post handelt, das Dain vorgeschlagen hat.
Erstellen Sie außerdem einen Beitrag und einen Kommentar in der Konsole mit einigen sehr einfachen Inhalten, um festzustellen, ob er funktioniert.
$ ruby script/console
# add whatever fields are necessary to create
> @p = Post.create(:title => "TestPost1")
# => #<Post id: 3, ...
# again, add whatever is necessary to create
> @c = @p.comments.create(:comment => "TestComment1")
# => #<Comment id: 8, ...
> Post.find(:last).comments_count
# => 1
Sehen Sie, was Sie dazu bringt.
/ JP
Andere Tipps
Dies mag vollständig von der Marke sein, aber Sie verwenden @posts dann @post?
ArgumentError in commentsController#erstellen
Falsche Anzahl von Argumenten (2 für 0)
Sie erhalten diesen Fehler, da @Comment nicht das Objekt ist, das Sie erwarten. Versuchen Sie, dies zu debuggen, indem Sie einfügen:
logger.debug @comment.inspect
Sie werden etwas Unerwartetes sehen und es sollte zumindest eine Augenbraue erhöhen. Dies sollte der Clou sein, den Sie dem zugewiesen haben Post.find(...)
zu @posts
aber später versuchte mit zu arbeiten mit @post
.