0

Not exactly sure how to look this up, but I'm not finding the solution anywhere. I want to assign an array of users an array of websites. Like so:

users = User.all
sites = Site.all

users.each do |user|
  sites.each do |site|
     user.websites << site
  end
end

Obviously, this does not work because I'm missing something about block scope. However, this works:

users.each do |user|
  Site.all.each do |site|
    user.websites << site
  end
end

But I'm trying to eliminate the extra calls to the DB (Site.all.each ...) and learn something about Ruby in the process. Any help is greatly appreciated.

2
  • Maybe I am missing something, but why does the first way not work, what is the error message? Commented Oct 25, 2009 at 6:45
  • First one looks good. How is it failing? Commented Oct 25, 2009 at 7:51

2 Answers 2

1

I'm not sure why the first attempt wouldn't work, but I also don't really understand why you'd append each site separately. Wouldn't this work?

users = User.all
sites = Site.all

users.each do |user|
    user.websites.concat(sites)
end

ruby-doc link to concat

If they're actually hashes (although you say they're arrays), the method you're looking for is merge

Sign up to request clarification or add additional context in comments.

Comments

0

If your User model is in a has many relationship with Websites (classname Sites), then you can just do

users = User.all
sites = Site.all

users.each do |user|
  user.websites = sites
end

Edit: For Harpastum:

If user.websites contains items not in Site.all that you don't want over written the following works.

users = User.all
sites = Site.all

users.each do |user|
  user.websites << sites
end

3 Comments

I'm new to rails, but wouldn't that set the value of user.websites to just the new array? i.e. Wouldn't any previous records in user.websites get overwritten?
Yes. But, it wouldn't matter given the assumption of a has_many relationship. There could be no items in websites that don't exist in Site.all
Thanks once again, EmFi. You're a big help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.