I'm trying to write a rake task that iterates through all my users in a Ruby on Rails project then makes changes to them. I know enough Ruby to make this work for one user, and I've done this successfully, now I want to iterate through all users and do the same.
This is my current code:
namespace :abc do
desc "Used to generate a new daily log"
STARTING_DATE = Date.new(2017, 04, 03)
task :create_post => :environment do
User.all.each do |currentUser|
Post.create!(content: "RAKED") if Date.today >= STARTING_DATE
end
puts "It worked yo"
end
end
The problem area is the iterating through the users. The error I get as its currently written is: "ActiveRecord::RecordInvalid: Validation failed: User must exist, User can't be blank"
Does anyone know the proper Ruby way of iterating through users like this?
Also, I've tried the following code:
User.all.each do |currentUser|
puts currentUser.name
end
And it will correctly display the name of each User. So it perhaps has something to do with my Users interacting with the Post.create! line?
Thanks!
I believe it's because you haven't initialised @users
to refer to all your users.
Try adding @users = User.all
before the for-each loop.
Without your codes for Post
model, I guess it has an association like:
belongs_to: user
That is why it gives error User must exist
. Check this link for the Github discussion. It was added in Rails 5 so I suppose, that is your Rails version too.
Add association like this belongs_to :user, optional: true
to make this function like it used to be before Rails 5.
For the error User can't be blank
, I think it is because you have added another extra validation to your Post
model, like below:
validates :user, :presence => true
So if a user foreign key is not mandatory for every Post record then you have to remove this validation and use optional: true
as I suggested above. Otherwise If you keep this validation or not going to use optional
flag then you have to supply a User
to every post you create. Maybe you can try modifying your code like below:
User.all.each do |currentUser|
Post.create!(content: "RAKED", user: currentUser) if Date.today >= STARTING_DATE
end
On a side note: Depending on your database size(no. of Users record), you should avoid User.all
since it will load all users to memory and in production, it may consume too much memory. find_in_batches can be a good alternative.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.