Come implementare una cache contatore in Rails?
-
23-10-2019 - |
Domanda
Ho un regolatore di messaggi e un controller commenti. Messaggio ha molti commenti, e commenti appartengono a Post. Il socio è impostato con l'opzione counter_cache acceso in quanto tale:
#Inside post.rb
has_many :comments
#Inside comment.rb
belongs_to :post, :counter_cache => true
Ho una colonna comments_count
in mia tabella posts
che è in default a zero, come ad esempio:
add_column :posts, :comments_count, :integer, :default => 0
Nel azione create
del mio controller commenti, ho il seguente codice:
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
Il mio problema: quando si chiama @comment.save
, ottengo il seguente errore:
ArgumentError in CommentsController#create
wrong number of arguments (2 for 0)
La rimozione :counter_cache => true
da comment.rb risolve completamente il problema, in modo da sto supponendo che è la causa di questo errore vago. Che cosa mi manca qui?
Come posso salvare il mio commento e hanno ancora le rotaie prendersi cura della mia counter_cache per il mio post?
Grazie!
Aggiornamento - traccia di domanda allegato:
/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'
Avviso l'unica linea che non ha a che fare direttamente con il quadro Rails è:
/Users/yuval/Sites/rails/blog/app/controllers/comments_controller.rb:6:in `create'
Linea 6 è il seguente:
if @comment.save
EDIT 2:. il @posts
/ @post
è un errore di battitura sulla mia estremità quando si scrive un esempio semplificato per StackOverflow, la mia domanda effettiva non ha errore
Controllo @comment
, sembra essere del tutto valida - torna indietro esattamente quello che mi aspetto che - una nuova istanza di commentare qualsiasi informazione ho passato ad essa con build
. Soffia solo quando il metodo save
viene chiamato su di esso.
Grazie per tutti i suggerimenti finora. Tutte le altre idee?
Soluzione
I attraversava un campione rotaie app con il tuo codice e tutto ha funzionato bene per me.
Vorrei suggerire il debug di un po 'più come hurikhan77 sta suggerendo e vedere se è solo il @posts / problema @post che Dain suggerito.
Inoltre, provare a creare un post e un commento nella console con alcuni contenuti molto semplice per vedere se funziona.
$ 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
Guarda cosa che si ottiene.
/ JP
Altri suggerimenti
Questo potrebbe essere completamente fuori luogo, ma è utilizzare @posts poi @post?
ArgumentError in CommentsController # crea
numero errato di argomenti (2 per 0)
Si ottiene questo errore perché @comment non è l'oggetto che ci si aspetta. Prova a eseguire il debug di questo con l'inserimento di:
logger.debug @comment.inspect
Si vedrà qualcosa di inaspettato e dovrebbe raccogliere almeno un sopracciglio. Questo dovrebbe essere il clou che si è assegnato il Post.find(...)
a @posts
ma in seguito cercato di lavorare con @post
.