Class: Relation

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

Overview

A relation defines a type of tie. Relations are 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.

Strength hierarchies

Relations are arranged in strength hierarchies, denoting that some ties between two actors are stronger than others. For example, a “friend” relation is stronger than an “acquaintance” relation.

When a strong tie is established, ties with weaker relations are establised as well

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. The Relation sets up the mode in which the Activity is shared. 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


103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'app/models/relation.rb', line 103

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)


128
129
130
# File 'app/models/relation.rb', line 128

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

.negative_namesObject

Negative relations: [ ‘Relation::Reject’ ]



94
95
96
# File 'app/models/relation.rb', line 94

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



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/models/relation.rb', line 58

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



77
78
79
80
81
82
83
84
85
86
# File 'app/models/relation.rb', line 77

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



89
90
91
# File 'app/models/relation.rb', line 89

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

Instance Method Details

#modeObject

Relation class scoped in the same mode that this relation



134
135
136
# File 'app/models/relation.rb', line 134

def mode
  Relation.mode(sender_type, receiver_type)
end

#positive?Boolean

Is this Relation a Positive one?

Returns:

  • (Boolean)


139
140
141
# File 'app/models/relation.rb', line 139

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