Class: Relation

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/relation.rb

Overview

A relation defines a type of Tie between two Actors. From social literature, Relations can be affective (friendship, liking, respect), formal or biological (authority, kinship), transfer of material resources (transactions, lending and borrowing), messages or conversations, physical connection and affiliation to same organizations.

Relation types defined in Social Stream

All the above cases could be supported in Social Stream. Nevertheless, the following Relations are defined. All of them inherit from the Relation class:

Custom

user-defined Relation. Every Subject is able to define their own Custom relation, giving them a custom name (for instance: friend, colleague, partner, buddy) and Permissions.

Public

default Relation for ocassional Ties.

Reject

the Subject does not want to add the other as a contact. A new Tie is created using this Relation

You can define new Relations in your application. Just create a new class and inherit from Relation. This class already supports Single Table Inheritance (STI).

Relations and link building

When a Subject creates a new link to other Subject, she must specify one or serveral Relations for that link. (friend, colleague, Public or Reject. A new Tie will be created for each Relation

Permissions

Subjects assign permissions to Relations. This way, when establishing ties, they are granting permissions to their contacts.

See the documentation of Permission for more details on permission definition.

Activities and Relations

Each Activity can be attached to one or more relations. It sets the Audience that has access to it, and the Permissions that rule that access.

Direct Known Subclasses

Custom, Single

Defined Under Namespace

Classes: Custom, CustomsController, Public, Reject, Single

Constant Summary collapse

Positive =
%w{ custom public }
Negative =
%w{ reject }

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.allow(subject, action, object, options = {}) ⇒ Object

All the relations that allow subject to perform action

Options:

in:: Limit possible relations to a set
public_relations:: include also {Relation::Public} whose activities can always be read


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/models/relation.rb', line 120

def allow(subject, action, object, options = {})
  q = 
    select("DISTINCT relations.*").
    joins(:contacts).
    joins(:permissions)

  conds =
    Permission.arel_table[:action].eq(action).and(Permission.arel_table[:object].eq(object))

  # Relation::Public permissions cannot be customized yet
  if action == 'read' && object == 'activity' && (options[:public].nil? || options[:public])
    conds = conds.or(Relation.arel_table[:type].eq('Relation::Public'))
  end

  # Add in condition
  if ! options[:in].nil?
    conds = conds.and(Relation.arel_table[:id].in(Relation.normalize_id(Array(options[:in]))))
  end

  # subject conditions
  conds = conds.and(Contact.arel_table[:receiver_id].eq(Actor.normalize_id(subject)))

  q.where(conds)
end

.allow?(*args) ⇒ Boolean

Returns:

  • (Boolean)


145
146
147
# File 'app/models/relation.rb', line 145

def allow?(*args)
  allow(*args).to_a.any?
end

.negative_namesObject

Negative relations: [ ‘Relation::Reject’ ]



111
112
113
# File 'app/models/relation.rb', line 111

def negative_names
  Negative.map{ |r| "Relation::#{ r.classify }" }
end

.normalize(r, options = {}) ⇒ Object

Get relation from object, if possible

Options
sender

The sender of the tie



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'app/models/relation.rb', line 75

def normalize(r, options = {})
  case r
  when Relation
    r
  when String
    if options[:sender]
      options[:sender].relation_custom(r)
    else
      raise "Must provide a sender when looking up relations from name: #{ options[:sender] }"
    end
  when Integer
    Relation.find r
  when Array
    r.map{ |e| Relation.normalize(e, options) }
  else
    raise "Unable to normalize relation #{ r.class }: #{ r.inspect }"
  end
end

.normalize_id(r, options = {}) ⇒ Object



94
95
96
97
98
99
100
101
102
103
# File 'app/models/relation.rb', line 94

def normalize_id(r, options = {})
  case r
  when Integer
    r
  when Array
    r.map{ |e| Relation.normalize_id(e, options) }
  else
    normalize(r, options).id
  end
end

.positive_namesObject

Positive relation names: [ ‘Relation::Custom’, ‘Relation::Public’ ]



106
107
108
# File 'app/models/relation.rb', line 106

def positive_names
  Positive.map{ |r| "Relation::#{ r.classify }" }
end

Instance Method Details

#modeObject

Relation class scoped in the same mode that this relation



151
152
153
# File 'app/models/relation.rb', line 151

def mode
  Relation.mode(sender_type, receiver_type)
end

#positive?Boolean

Is this Relation a Positive one?

Returns:

  • (Boolean)


156
157
158
# File 'app/models/relation.rb', line 156

def positive?
  self.class.positive_names.include?(self.class.to_s)
end