Rails5新手求助:无需表单如何将数据存入Post模型表?
total_votes to Your Post Model in Rails Hey there! Let's break this down step by step since you're new to Rails—no worries, this is a super common scenario when working with calculated fields.
1. The Direct Way: Save the Instance Immediately
Once you've set @post.total_votes = @post.votes.sum(:vote), all you need to do is persist that change to the database using Rails' built-in save methods:
- Use
@post.saveif you want a boolean return value (trueif successful,falseif validation fails) - Use
@post.save!if you want Rails to raise an error if something goes wrong (great for debugging when you're starting out)
Example code snippet:
@post = Post.find(params[:id]) @post.total_votes = @post.votes.sum(:vote) @post.save! # or @post.save
2. Automate It with Model Callbacks
To avoid manually running this calculation every time, you can add a callback to your Post model. This way, Rails will automatically update total_votes whenever you save a Post.
Add this to your app/models/post.rb:
class Post < ApplicationRecord has_many :votes # Update total_votes before saving the post before_save :update_total_votes private def update_total_votes # Use `self` here to make sure we're setting the model attribute, not a local variable self.total_votes = votes.sum(:vote) end end
Now, whenever you save a Post (e.g., @post.save), Rails will run the update_total_votes method first, calculate the sum, and save it to the database automatically.
3. Optimize for Vote Changes (Even Better!)
If you want total_votes to update every time a vote is added or removed (instead of only when the Post is saved), you can add callbacks to your Vote model. This is more efficient because it only recalculates when votes change, not on every Post save.
Add this to your app/models/vote.rb:
class Vote < ApplicationRecord belongs_to :post after_create :update_post_total_votes after_destroy :update_post_total_votes private def update_post_total_votes post.update(total_votes: post.votes.sum(:vote)) end end
4. Update Existing Posts (One-Time Fix)
If you already have Posts and Votes in your database, you'll need to backfill the total_votes field for existing records. Run this in your Rails console (rails c):
Post.find_each do |post| post.update(total_votes: post.votes.sum(:vote)) end
That's it! Pick the approach that fits your workflow best—starting with the direct save method is totally fine when you're learning, and you can move to callbacks as you get more comfortable.
内容的提问来源于stack exchange,提问作者Raluca Cristina Dumitru

