简体   繁体   中英

How To Iterate Through All My Ruby on Rails Users In A Rake File?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM