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 = nil) ⇒ 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.
-
#relations_for_button ⇒ Object
The relations offered in the “Add contact” button when subjects add new contacts.
-
#relations_list ⇒ Object
The relations that will appear in privacy forms.
-
#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
368 369 370 |
# File 'app/models/actor.rb', line 368 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
373 374 375 376 |
# File 'app/models/actor.rb', line 373 def action_to!(activity_object) action_to(activity_object) || sent_actions.create!(:activity_object => ActivityObject.normalize(activity_object)) end |
#activity_relation_ids ⇒ Object
446 447 448 |
# File 'app/models/actor.rb', line 446 def activity_relation_ids activity_relations.map(&:id) end |
#activity_relations ⇒ Object
437 438 439 440 441 442 |
# File 'app/models/actor.rb', line 437 def activity_relations SocialStream.relation_model == :custom ? relations. allowing('read', 'activity') : [ Relation::Public.instance ] end |
#activity_relations_for(subject, options = {}) ⇒ Object
454 455 456 457 458 459 460 |
# File 'app/models/actor.rb', line 454 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?
463 464 465 |
# File 'app/models/actor.rb', line 463 def activity_relations_for?(subject, = {}) activity_relations(subject, ).any? end |
#allow?(subject, action, object = nil) ⇒ Boolean
Does this Actor allow subject to perform action on object?
363 364 365 |
# File 'app/models/actor.rb', line 363 def allow?(subject, action, object = nil) ties_to(subject).(action, object).any? end |
#as_json(options) ⇒ Object
508 509 510 511 512 513 514 515 516 517 518 |
# File 'app/models/actor.rb', line 508 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
158 159 160 |
# File 'app/models/actor.rb', line 158 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
470 471 472 473 474 |
# File 'app/models/actor.rb', line 470 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?
477 478 479 480 |
# File 'app/models/actor.rb', line 477 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
499 500 501 |
# File 'app/models/actor.rb', line 499 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
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 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'app/models/actor.rb', line 249 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
308 309 310 311 312 313 314 315 316 |
# File 'app/models/actor.rb', line 308 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.
324 325 326 |
# File 'app/models/actor.rb', line 324 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
329 330 331 332 |
# File 'app/models/actor.rb', line 329 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
417 418 419 420 |
# File 'app/models/actor.rb', line 417 def egocentric_ties @egocentric_ties ||= load_egocentric_ties end |
#following_actor_and_self_ids ⇒ Object
358 359 360 |
# File 'app/models/actor.rb', line 358 def following_actor_and_self_ids following_actor_ids + [ id ] end |
#following_actor_ids ⇒ Object
349 350 351 352 353 354 |
# File 'app/models/actor.rb', line 349 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
343 344 345 346 |
# File 'app/models/actor.rb', line 343 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.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'app/models/actor.rb', line 167 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
491 492 493 494 495 496 |
# File 'app/models/actor.rb', line 491 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
486 487 488 |
# File 'app/models/actor.rb', line 486 def pending_contacts? pending_contacts_count > 0 end |
#pending_contacts_count ⇒ Object
482 483 484 |
# File 'app/models/actor.rb', line 482 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
319 320 321 |
# File 'app/models/actor.rb', line 319 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
206 207 208 |
# File 'app/models/actor.rb', line 206 def relation_custom(name) relation_customs.find_by_name(name) end |
#relation_customs ⇒ Object
201 202 203 |
# File 'app/models/actor.rb', line 201 def relation_customs relations.where(:type => 'Relation::Custom') end |
#relation_notifys ⇒ Object
All relations with the ‘notify’ permission
211 212 213 |
# File 'app/models/actor.rb', line 211 def relation_notifys relations.joins(:relation_permissions => :permission).where('permissions.action' => 'notify') end |
#relations_for_button ⇒ Object
The relations offered in the “Add contact” button when subjects add new contacts
225 226 227 |
# File 'app/models/actor.rb', line 225 def relations_list end |
#relations_list ⇒ Object
The relations that will appear in privacy forms
They usually include Relation::Custom but may also include other system-defined relations that are not editable but appear in add contact buttons
219 220 221 |
# File 'app/models/actor.rb', line 219 def relations_list Relation.extra_list(subject) + relation_customs end |
#represented_by?(subject) ⇒ Boolean
Can this actor be represented by subject. Does she has permissions for it?
424 425 426 427 428 429 430 431 432 433 |
# File 'app/models/actor.rb', line 424 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
335 336 337 |
# File 'app/models/actor.rb', line 335 def self_contact contact_to!(self) end |
#sent_active_contact_count ⇒ Object
378 379 380 |
# File 'app/models/actor.rb', line 378 def sent_active_contact_count sent_contacts.active.count end |
#sent_active_contact_ids ⇒ Object
382 383 384 385 |
# File 'app/models/actor.rb', line 382 def sent_active_contact_ids @sent_active_contact_ids ||= load_sent_active_contact_ids end |
#subject ⇒ Object
The subject instance for this actor
196 197 198 |
# File 'app/models/actor.rb', line 196 def subject subtype_instance end |
#suggestions(size = 1) ⇒ Contact
393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'app/models/actor.rb', line 393 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
407 408 409 |
# File 'app/models/actor.rb', line 407 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
412 413 414 |
# File 'app/models/actor.rb', line 412 def ties_to?(subject) ties_to(subject).present? end |
#to_param ⇒ Object
Use slug as parameter
504 505 506 |
# File 'app/models/actor.rb', line 504 def to_param slug end |