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, Follow, Public, Reject, Single

Constant Summary collapse

Positive =
%w{ custom public follow }
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


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'app/models/relation.rb', line 129

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 and should not depend on the subject
  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)


154
155
156
# File 'app/models/relation.rb', line 154

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

.ids_shared_with(subject) ⇒ Object

All the Relation ids in Ties this subject has received plus the one from Public



160
161
162
163
164
165
166
167
168
169
170
171
# File 'app/models/relation.rb', line 160

def ids_shared_with(subject)
  ids = [Relation::Public.instance.id]

  if SocialStream.relation_model == :custom && subject.present?
    # Subject own defined custom relations
    ids += subject.relation_ids
    # From Ties sent by other subject
    ids += subject.received_relation_ids
  end

  ids
end

.negative_namesObject

Negative relations: [ ‘Relation::Reject’ ]



120
121
122
# File 'app/models/relation.rb', line 120

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



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'app/models/relation.rb', line 84

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



103
104
105
106
107
108
109
110
111
112
# File 'app/models/relation.rb', line 103

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’ ]



115
116
117
# File 'app/models/relation.rb', line 115

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

Instance Method Details

#follow?Boolean

Does this relation include the follow permission?

Returns:

  • (Boolean)


185
186
187
# File 'app/models/relation.rb', line 185

def follow?
  permissions.follow.any?
end

#modeObject

Relation class scoped in the same mode that this relation



175
176
177
# File 'app/models/relation.rb', line 175

def mode
  Relation.mode(sender_type, receiver_type)
end

#positive?Boolean

Is this Relation a Positive one?

Returns:

  • (Boolean)


180
181
182
# File 'app/models/relation.rb', line 180

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