nobilik
nobilik

Reputation: 736

How to associate many users with one message at once?

I have posts that associated with many users. When somebody comment one of them, my app creates a message that should be delivered to users associated with post. I want to associate all commented post users with new message. How to do it at once, without iterator?

users.each do |user| 
  user.messages << message
end

Upvotes: 0

Views: 64

Answers (3)

Gagan Gami
Gagan Gami

Reputation: 10251

It sounds like you are looking for ActiveRecord::Base.update_all - from the documentation:

Updates all records with details given if they match a set of conditions supplied, limits and order can also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks.

you can do something like:

users.update_all(:messages => "your message")

I guess you have all users related the same post in your users object.

for your reference you can check this link too regarding update_all:

Updates all records in the current relation with details given. This method constructs a single SQL UPDATE statement and sends it straight to the database. It does not instantiate the involved models and it does not trigger Active Record callbacks or validations. Values passed to update_all will not go through ActiveRecord's type-casting behavior. It should receive only values that can be passed as-is to the SQL database.

Upvotes: 4

Minato
Minato

Reputation: 4533

I saw this answer Can you supply arguments to the map(&:method) syntax in Ruby?

I do not recommend it but your can hack your way around by monkey patching the Symbol class in your initializer like

class Symbol
  def call(*args, &block)
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
  end
end

and in your User model adding a simple method like

def addMessage(message)
   self.messages << message
end

and in your code simply replace this

users.each do |user| 
  user.messages << message
end

with

users.map(&:addMessage.(message))

this is actually the same thing but it hides away the iterative style code to a simple map

I would NOT recommend doing this but I found it rather fun to play around with.

Upvotes: 0

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

AFAIK, this is not achievable with standard rails syntax, but you are still free to use plain old good SQL:

ActiveRecord::Base.connection.execute %Q{
  UPDATE users
  SET message_id = #{message.id}
  WHERE post_id = #{post.id}
}

The query above is likely not precisely correct, since you did not provide the relationship model, but I guess you get the point.

Upvotes: 1

Related Questions