Class: Actor
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Actor
- Includes:
- SocialStream::Models::Object
- Defined in:
- app/models/actor.rb
Overview
An Actor represents a social entity. This means individuals, but also groups, departments, organizations even nations or states.
Actors are the nodes of a social network. Two actors are linked by Ties. The type of a Tie is a Relation. Each actor can define and customize their relations own Relations.
Every Actor has an Avatar, a Profile with personal or group information, contact data, etc.
Actors perform actions (like, suscribe, etc.) on activity objects (posts, commments, pictures, events..)
Actor subtypes
An actor subtype is called a Subject. SocialStream::Base provides two actor subtypes, User and Group, but the application developer can define as many actor subtypes as required. Besides including the SocialStream::Models::Subject module, Actor subtypes must added to config/initializers/social_stream.rb
Instance Method Summary collapse
-
#action_to(activity_object) ⇒ Object
Return the ActivityAction model to an ActivityObject.
-
#action_to!(activity_object) ⇒ Object
Return the ActivityAction model to an ActivityObject.
- #activity_relation_ids ⇒ Object
- #activity_relations ⇒ Object
-
#activity_relations_for(subject, options = {}) ⇒ Object
This method returns all the Relation that subject can choose to broadcast an Activity in this Actor‘s wall.
-
#activity_relations_for?(subject, options = {}) ⇒ Boolean
Are #activity_relations available for subject?.
-
#allow?(subject, action, object) ⇒ Boolean
Does this Actor allow subject to perform action on object?.
- #as_json(options) ⇒ Object
-
#as_object_type ⇒ Object
FIXME SocialStream::ActivityStreams::Supertype should take precedence over SocialStream::ActivityStreams::Subtype.
-
#can_comment?(activity) ⇒ Boolean
Is this Actor allowed to create a comment on activity?.
-
#comment_relations(activity) ⇒ Object
Are there any relations that allow this actor to create a comment on activity?.
-
#common_contacts_count(subject) ⇒ Object
Count the contacts in common between this Actor and subject.
-
#contact_actors(options = {}) ⇒ Object
All the Actors this one has ties with:.
- #contact_subjects(options = {}) ⇒ Object
-
#contact_to(subject) ⇒ Object
Return a contact to subject.
-
#contact_to!(subject) ⇒ Object
Return a contact to subject.
-
#egocentric_ties ⇒ Object
The ties sent by this actor, plus the second grade ties.
- #following_actor_and_self_ids ⇒ Object
- #following_actor_ids ⇒ Object
-
#following_actor_objects ⇒ Object
The ActivityObjects followed by this Actor that are Actors.
-
#mailboxer_email(object) ⇒ Object
Returning the email address of the model if an email should be sent for this object (Message or Notification).
-
#pending_contacts ⇒ Object
Build a new Contact from each that has not inverse.
- #pending_contacts? ⇒ Boolean
- #pending_contacts_count ⇒ Object
-
#positive_sent_contact_actors ⇒ Object
The actors this one has established positive ties with.
-
#relation_custom(name) ⇒ Object
A given relation defined and managed by this actor.
- #relation_customs ⇒ Object
-
#relation_notifys ⇒ Object
All relations with the ‘notify’ permission.
-
#represented_by?(subject) ⇒ Boolean
Can this actor be represented by subject.
- #self_contact ⇒ Object (also: #ego_contact)
- #sent_active_contact_count ⇒ Object
- #sent_active_contact_ids ⇒ Object
-
#subject ⇒ Object
The subject instance for this actor.
- #suggestions(size = 1) ⇒ Contact
-
#ties_to(subject) ⇒ Object
Set of ties sent by this actor received by subject.
-
#ties_to?(subject) ⇒ Boolean
Is there any Tie sent by this actor and received by subject.
-
#to_param ⇒ Object
Use slug as parameter.
Instance Method Details
#action_to(activity_object) ⇒ Object
Return the ActivityAction model to an ActivityObject
342 343 344 |
# File 'app/models/actor.rb', line 342 def action_to(activity_object) sent_actions.received_by(activity_object).first end |
#action_to!(activity_object) ⇒ Object
Return the ActivityAction model to an ActivityObject. Create it if it does not exist
347 348 349 350 |
# File 'app/models/actor.rb', line 347 def action_to!(activity_object) action_to(activity_object) || sent_actions.create!(:activity_object => ActivityObject.normalize(activity_object)) end |
#activity_relation_ids ⇒ Object
420 421 422 |
# File 'app/models/actor.rb', line 420 def activity_relation_ids activity_relations.map(&:id) end |
#activity_relations ⇒ Object
411 412 413 414 415 416 |
# File 'app/models/actor.rb', line 411 def activity_relations SocialStream.relation_model == :custom ? relations. allowing('read', 'activity') : [ Relation::Public.instance ] end |
#activity_relations_for(subject, options = {}) ⇒ Object
428 429 430 431 432 433 434 |
# File 'app/models/actor.rb', line 428 def activity_relations_for(subject, = {}) if Actor.normalize(subject) == self return relation_customs + Array.wrap(Relation::Public.instance) else Array.new end end |
#activity_relations_for?(subject, options = {}) ⇒ Boolean
Are #activity_relations available for subject?
437 438 439 |
# File 'app/models/actor.rb', line 437 def activity_relations_for?(subject, = {}) activity_relations(subject, ).any? end |
#allow?(subject, action, object) ⇒ Boolean
Does this Actor allow subject to perform action on object?
337 338 339 |
# File 'app/models/actor.rb', line 337 def allow?(subject, action, object) ties_to(subject).(action, object).any? end |
#as_json(options) ⇒ Object
482 483 484 485 486 487 488 489 490 491 492 |
# File 'app/models/actor.rb', line 482 def as_json() { id: id, slug: slug, name: name, url: [:helper].polymorphic_url(subject), image: { url: [:helper].root_url + logo.url(:small) } } end |
#as_object_type ⇒ Object
FIXME SocialStream::ActivityStreams::Supertype should take precedence over SocialStream::ActivityStreams::Subtype
146 147 148 |
# File 'app/models/actor.rb', line 146 def as_object_type subtype_instance.as_object_type end |
#can_comment?(activity) ⇒ Boolean
Is this Actor allowed to create a comment on activity?
We are allowing comments from everyone signed in by now
444 445 446 447 448 |
# File 'app/models/actor.rb', line 444 def can_comment?(activity) return true comment_relations(activity).any? end |
#comment_relations(activity) ⇒ Object
Are there any relations that allow this actor to create a comment on activity?
451 452 453 454 |
# File 'app/models/actor.rb', line 451 def comment_relations(activity) activity.relations.select{ |r| r.is_a?(Relation::Public) } | Relation.allow(self, 'create', 'activity', :in => activity.relations) end |
#common_contacts_count(subject) ⇒ Object
Count the contacts in common between this Actor and subject
473 474 475 |
# File 'app/models/actor.rb', line 473 def common_contacts_count(subject) (sent_active_contact_ids & subject.sent_active_contact_ids).size end |
#contact_actors(options = {}) ⇒ Object
All the Actors this one has ties with:
actor.contact_actors #=> array of actors that sent and receive ties from actor
There are several options available to refine the query:
- type
-
Filter by the class of the contacts (User, Group, etc.)
actor.contact_actors(:type => :user) #=> array of user actors. Exclude groups, etc.
- direction
-
:sent
leaves only the actors this one has ties to.:received
gets the actors sending ties to this actor, whether this actor added them or notactor.contact_actors(:direction => :sent) #=> all the receivers of ties from actor
- relations
-
Restrict to ties made up with
relations
. In the case of both directions, only relations belonging to Actor are considered. It defaults to actor’s custom relationsactor.contact_actors(:relations => [2]) #=> actors tied with relation #2
- include_self
-
False by default, do not include this actor even they have ties with themselves.
- load_subjects
-
True by default, make the queries for eager loading of Subject
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'app/models/actor.rb', line 223 def contact_actors( = {}) subject_types = Array([:type] || self.class.subtypes) subject_classes = subject_types.map{ |s| s.to_s.classify } as = Actor.select('actors.*'). # PostgreSQL requires that all the columns must be included in the GROUP BY group((Actor.columns.map(&:name).map{ |c| "actors.#{ c }" } + [ "contacts.created_at" ]).join(", ")). where('actors.subject_type' => subject_classes) if [:load_subjects].nil? || [:load_subjects] as = as.includes(subject_types) end # A blank :direction means reciprocate contacts, there must be ties in both directions # # This is achieved by getting the id of all the contacts that are sending ties # Then, we filter the sent contacts query to only those contacts if [:direction].blank? rcv_opts = .dup rcv_opts[:direction] = :received rcv_opts[:load_subjects] = false # Get the id of actors that are sending to this one sender_ids = contact_actors(rcv_opts).map(&:id) # Filter the sent query with these ids as = as.where(:id => sender_ids) [:direction] = :sent end case [:direction] when :sent as = as.joins(:received_ties => :relation).merge(Contact.sent_by(self)) when :received as = as.joins(:sent_ties => :relation).merge(Contact.received_by(self)) else raise "How do you get here?!" end if [:include_self].blank? as = as.where("actors.id != ?", self.id) end if [:relations].present? as = as.merge(Tie.([:relations])) else as = as.merge(Relation.where(:type => ['Relation::Custom', 'Relation::Public'])) end as end |
#contact_subjects(options = {}) ⇒ Object
282 283 284 285 286 287 288 289 290 |
# File 'app/models/actor.rb', line 282 def contact_subjects( = {}) as = contact_actors() if block_given? as = yield(as) end as.map(&:subject) end |
#contact_to(subject) ⇒ Object
Return a contact to subject.
298 299 300 |
# File 'app/models/actor.rb', line 298 def contact_to(subject) sent_contacts.received_by(subject).first end |
#contact_to!(subject) ⇒ Object
Return a contact to subject. Create it if it does not exist
303 304 305 306 |
# File 'app/models/actor.rb', line 303 def contact_to!(subject) contact_to(subject) || sent_contacts.create!(:receiver => Actor.normalize(subject)) end |
#egocentric_ties ⇒ Object
The ties sent by this actor, plus the second grade ties
391 392 393 394 |
# File 'app/models/actor.rb', line 391 def egocentric_ties @egocentric_ties ||= load_egocentric_ties end |
#following_actor_and_self_ids ⇒ Object
332 333 334 |
# File 'app/models/actor.rb', line 332 def following_actor_and_self_ids following_actor_ids + [ id ] end |
#following_actor_ids ⇒ Object
323 324 325 326 327 328 |
# File 'app/models/actor.rb', line 323 def following_actor_ids following_actor_objects. includes(:actor). map(&:actor). map(&:id) end |
#following_actor_objects ⇒ Object
The ActivityObjects followed by this Actor that are Actors
317 318 319 320 |
# File 'app/models/actor.rb', line 317 def following_actor_objects followings. where('activity_objects.object_type' => "Actor") end |
#mailboxer_email(object) ⇒ Object
Returning the email address of the model if an email should be sent for this object (Message or Notification). If the actor is a Group and has no email address, an array with the email of the highest rank members will be returned isntead.
If no mail has to be sent, return nil.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'app/models/actor.rb', line 155 def mailboxer_email(object) #If actor has disabled the emails, return nil. return nil if !notify_by_email #If actor has enabled the emails and has email return "#{name} <#{email}>" if email.present? #If actor is a Group, has enabled emails but no mail we return the highest_rank ones. if (group = self.subject).is_a? Group emails = Array.new group.relation_notifys.each do |relation| receivers = group.contact_actors(:direction => :sent, :relations => relation) receivers.each do |receiver| next unless Actor.normalize(receiver).subject_type.eql?("User") receiver_emails = receiver.mailboxer_email(object) case receiver_emails when String emails << receiver_emails when Array receiver_emails.each do |receiver_email| emails << receiver_email end end end end return emails end end |
#pending_contacts ⇒ Object
Build a new Contact from each that has not inverse
465 466 467 468 469 470 |
# File 'app/models/actor.rb', line 465 def pending_contacts received_contacts.pending.includes(:inverse).all.map do |c| c.inverse || c.receiver.contact_to!(c.sender) end end |
#pending_contacts? ⇒ Boolean
460 461 462 |
# File 'app/models/actor.rb', line 460 def pending_contacts? pending_contacts_count > 0 end |
#pending_contacts_count ⇒ Object
456 457 458 |
# File 'app/models/actor.rb', line 456 def pending_contacts_count received_contacts.not_reflexive.pending.count end |
#positive_sent_contact_actors ⇒ Object
The actors this one has established positive ties with
293 294 295 |
# File 'app/models/actor.rb', line 293 def positive_sent_contact_actors sent_contacts.joins(ties: :relation).merge(Relation.positive) end |
#relation_custom(name) ⇒ Object
A given relation defined and managed by this actor
194 195 196 |
# File 'app/models/actor.rb', line 194 def relation_custom(name) relation_customs.find_by_name(name) end |
#relation_customs ⇒ Object
189 190 191 |
# File 'app/models/actor.rb', line 189 def relation_customs relations.where(:type => 'Relation::Custom') end |
#relation_notifys ⇒ Object
All relations with the ‘notify’ permission
199 200 201 |
# File 'app/models/actor.rb', line 199 def relation_notifys relations.joins(:relation_permissions => :permission).where('permissions.action' => 'notify') end |
#represented_by?(subject) ⇒ Boolean
Can this actor be represented by subject. Does she has permissions for it?
398 399 400 401 402 403 404 405 406 407 |
# File 'app/models/actor.rb', line 398 def represented_by?(subject) return false if subject.blank? self.class.normalize(subject) == self || sent_ties. merge(Contact.received_by(subject)). joins(:relation => :permissions). merge(Permission.represent). any? end |
#self_contact ⇒ Object Also known as: ego_contact
309 310 311 |
# File 'app/models/actor.rb', line 309 def self_contact contact_to!(self) end |
#sent_active_contact_count ⇒ Object
352 353 354 |
# File 'app/models/actor.rb', line 352 def sent_active_contact_count sent_contacts.active.count end |
#sent_active_contact_ids ⇒ Object
356 357 358 359 |
# File 'app/models/actor.rb', line 356 def sent_active_contact_ids @sent_active_contact_ids ||= load_sent_active_contact_ids end |
#subject ⇒ Object
The subject instance for this actor
184 185 186 |
# File 'app/models/actor.rb', line 184 def subject subtype_instance end |
#suggestions(size = 1) ⇒ Contact
367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'app/models/actor.rb', line 367 def suggestions(size = 1) candidates = Actor. where(subject_type: SocialStream.suggested_models.map{ |m| m.to_s.classify }). where(Actor.arel_table[:id].not_in(sent_active_contact_ids + [id])) size.times.map { candidates.delete_at rand(candidates.size) }.compact.map { |a| contact_to! a } end |
#ties_to(subject) ⇒ Object
Set of ties sent by this actor received by subject
381 382 383 |
# File 'app/models/actor.rb', line 381 def ties_to(subject) sent_ties.merge(Contact.received_by(subject)) end |
#ties_to?(subject) ⇒ Boolean
Is there any Tie sent by this actor and received by subject
386 387 388 |
# File 'app/models/actor.rb', line 386 def ties_to?(subject) ties_to(subject).present? end |
#to_param ⇒ Object
Use slug as parameter
478 479 480 |
# File 'app/models/actor.rb', line 478 def to_param slug end |