Module: Zena::Use::Relations::ModelMethods
- Included in:
- Node
- Defined in:
- lib/zena/use/relations.rb
Class Method Summary collapse
Instance Method Summary collapse
-
#add_link(role, hash) ⇒ Object
FIXME: this method does an ‘update’ not only ‘add’.
- #all_relations ⇒ Object
-
#l_comment ⇒ Object
comment defined through loading link.
- #l_comment=(v) ⇒ Object
-
#l_date ⇒ Object
date defined through loading link.
- #l_date=(v) ⇒ Object
-
#l_status ⇒ Object
status defined through loading link.
- #l_status=(v) ⇒ Object
- #link_id ⇒ Object
- #link_id=(v) ⇒ Object
- #linked_node ⇒ Object
-
#linked_node=(node) ⇒ Object
Linked_node is a way to store a linked node during calendar display or ajax return calls so the template knows which “couple” has just been formed or removed.
- #rel ⇒ Object
-
#rel=(hash) ⇒ Object
This accessor is used when the data arrives with the syntax rel => { friend => … }.
- #rel_attributes=(hash) ⇒ Object
-
#relation_alias(match) ⇒ Object
Return an array of accessor methods for the matched relation alias.
-
#relation_links ⇒ Object
List the links, grouped by role.
-
#relation_proxy(role) ⇒ Object
Find relation proxy for the given role.
- #relation_proxy_from_link(link = nil) ⇒ Object
- #relations_for_form ⇒ Object
- #remove_link(link) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object (private)
Used to create / destroy / update links through pseudo methods ‘icon_id=’, ‘icon_status=’, … Pseudo methods created for a many-to-one relation (icon_for — icon):
- icon_id=
-
set icon
- icon_status=
-
set status field for link to icon
- icon_comment=
-
set comment field for link to icon
- icon_for_ids=
-
set all nodes for which the image is an icon (replaces old values)
- icon_for_id=
-
add a node for which the image is an icon (adds a new value)
- icon_id
-
get icon id
- icon_zip
-
get icon zip
- icon_status
-
get status field for link to icon
- icon_comment
-
get comment field for link to icon
- icon_for_ids
-
get all node ids for which the image is an icon
- icon_for_zips
-
get all node zips for which the image is an icon
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/zena/use/relations.rb', line 305 def method_missing(meth, *args, &block) # first try rails' version of method missing super(meth, *args, &block) rescue NoMethodError => err # 1. is this a method related to a relation ? if meth.to_s =~ LINK_REGEXP role = $1 field = $2 mode = $3 # 2. is this a valid role ? if rel = relation_proxy(role) if mode == '=' # set rel.send("other_#{field}=", args[0]) else # get if field != 'ids' && field != 'zips' && !rel.unique? # ask for a single value in a ..-to-many relation # 1. try to use focus if @link rel.other_link = @link elsif self.link_id @link = Link.find_through(self, self.link_id) rel.other_link = @link else return nil end end rel.send("other_#{field}") end else # invalid relation if mode == '=' errors.add(role, "invalid relation") unless args[0].blank? return args[0] else # ignore return nil end end else # not related to relations raise err end end |
Class Method Details
.included(base) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/zena/use/relations.rb', line 71 def self.included(base) base.extend Zena::Use::Relations::ClassMethods base.validate :relations_valid base.after_save :update_relations base.after_destroy :destroy_links base.safe_method :rel => ProxyLoader base.safe_method :l_status => {:class => Number, :nil => true} base.safe_method :l_comment => {:class => String, :nil => true} base.safe_method :l_date => {:class => Time, :nil => true} base.safe_method :link_id => {:class => Number, :nil => true} base.nested_attributes_alias LINK_REGEXP => Proc.new {|obj, m| obj.relation_alias(m) } base.class_eval <<-END attr_accessor :link class << self include Zena::Use::Relations::ClassMethods end def relation_base_class #{base} end HAS_RELATIONS = true END end |
Instance Method Details
#add_link(role, hash) ⇒ Object
FIXME: this method does an ‘update’ not only ‘add’
169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/zena/use/relations.rb', line 169 def add_link(role, hash) if rel = relation_proxy(role) rel.qb = hash[:qb] if hash.has_key?(:qb) rel.other_id = hash[:other_id] if hash.has_key?(:other_id) rel.other_ids = hash[:other_ids] if hash.has_key?(:other_ids) rel.other_zip = hash[:other_zip] if hash.has_key?(:other_zip) rel.other_zips = hash[:other_zips] if hash.has_key?(:other_zips) LINK_ATTRIBUTES.each do |k| rel.send("other_#{k}=", hash[k]) if hash.has_key?(k) end else errors.add(role, 'invalid relation') end end |
#all_relations ⇒ Object
248 249 250 |
# File 'lib/zena/use/relations.rb', line 248 def all_relations @all_relations ||= self.vclass.all_relations(self) end |
#l_comment ⇒ Object
comment defined through loading link
139 140 141 142 |
# File 'lib/zena/use/relations.rb', line 139 def l_comment return @l_comment if defined? @l_comment @link ? @link[:comment] : self['l_comment'] end |
#l_comment=(v) ⇒ Object
227 228 229 230 231 232 |
# File 'lib/zena/use/relations.rb', line 227 def l_comment=(v) @l_comment = v.blank? ? nil : v if rel = relation_proxy_from_link rel.other_comment = @l_comment end end |
#l_date ⇒ Object
date defined through loading link
145 146 147 148 |
# File 'lib/zena/use/relations.rb', line 145 def l_date return @l_date if defined? @l_date @l_date = @link ? @link[:date] : (self['l_date'] ? Time.parse(self['l_date']) : nil) end |
#l_date=(v) ⇒ Object
241 242 243 244 245 246 |
# File 'lib/zena/use/relations.rb', line 241 def l_date=(v) @l_date = v.blank? ? nil : v if rel = relation_proxy_from_link rel.other_date = @l_date end end |
#l_status ⇒ Object
status defined through loading link
130 131 132 133 134 |
# File 'lib/zena/use/relations.rb', line 130 def l_status return @l_status if defined? @l_status val = @link ? @link[:status] : self['l_status'] val ? val.to_i : nil end |
#l_status=(v) ⇒ Object
234 235 236 237 238 239 |
# File 'lib/zena/use/relations.rb', line 234 def l_status=(v) @l_status = v.blank? ? nil : v.to_i if rel = relation_proxy_from_link rel.other_status = @l_status end end |
#link_id ⇒ Object
150 151 152 |
# File 'lib/zena/use/relations.rb', line 150 def link_id @link ? @link[:id] : (self[:link_id] == -1 ? nil : self[:link_id]) # -1 == dummy link end |
#link_id=(v) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/zena/use/relations.rb', line 154 def link_id=(v) if @link && @link[:id].to_i != v.to_i @link = nil end self[:link_id] = v.to_i if @link_attributes_to_update if rel = relation_proxy_from_link @link_attributes_to_update.each do |k,v| rel.send("other_#{k}=",v) end end end end |
#linked_node ⇒ Object
125 126 127 |
# File 'lib/zena/use/relations.rb', line 125 def linked_node @linked_node ||= @relation_proxies ? @relation_proxies[@relation_proxies.keys.first].last_target : nil end |
#linked_node=(node) ⇒ Object
Linked_node is a way to store a linked node during calendar display or ajax return calls so the template knows which “couple” has just been formed or removed. The linked_node “node” must respond to “l_date”.
121 122 123 |
# File 'lib/zena/use/relations.rb', line 121 def linked_node=(node) @linked_node = node end |
#rel ⇒ Object
217 218 219 |
# File 'lib/zena/use/relations.rb', line 217 def rel ProxyLoader.new(self) end |
#rel=(hash) ⇒ Object
This accessor is used when the data arrives with the syntax rel => { friend => … }
223 224 225 |
# File 'lib/zena/use/relations.rb', line 223 def rel=(hash) self.rel_attributes = hash end |
#rel_attributes=(hash) ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/zena/use/relations.rb', line 197 def rel_attributes=(hash) return unless hash.kind_of?(Hash) hash.each do |role, definition| if role =~ /\A\d+\Z/ # key used as array elsif role =~ /^(.+)_attributes$/ # key used as role definition['role'] ||= $1 elsif definition.kind_of?(Hash) # key used as role, without the '_attributes' definition['role'] ||= role else # qb definition = {'role' => role, 'qb' => definition} end # TODO: only use string keys add_link(definition.delete('role'), definition.symbolize_keys) end end |
#relation_alias(match) ⇒ Object
Return an array of accessor methods for the matched relation alias.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/zena/use/relations.rb', line 100 def relation_alias(match) return nil if match[0] == 'parent_id' role = match[1] field = match[2] if relation = relation_proxy(role) # We use 'links' so that we can keep the old @link accessor. # FIXME: rename 'link' when we refactor the @link part. if field =~ /^ids?|zips?/ ['rel', role, "other_#{field}"] else ['rel', role, field] end else nil end end |
#relation_links ⇒ Object
List the links, grouped by role
257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/zena/use/relations.rb', line 257 def relation_links res = [] all_relations.each do |rel| #if relation.record_count > 5 # # FIXME: show message ? #end links = rel.records(:limit => 5, :order => "link_id DESC") res << [rel, links] if links end res end |
#relation_proxy(role) ⇒ Object
Find relation proxy for the given role.
270 271 272 273 274 |
# File 'lib/zena/use/relations.rb', line 270 def relation_proxy(role) @relation_proxies ||= {} return @relation_proxies[role] if @relation_proxies.has_key?(role) @relation_proxies[role] = RelationProxy.get_proxy(self, role.singularize.underscore) end |
#relation_proxy_from_link(link = nil) ⇒ Object
276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/zena/use/relations.rb', line 276 def relation_proxy_from_link(link = nil) unless link if @link link = @link elsif self.link_id link = @link = Link.find_through(self, self.link_id) end return nil unless link end @relation_proxies ||= {} return @relation_proxies[link.role] if @relation_proxies.has_key?(link.role) @relation_proxies[link.role] = link.relation_proxy(self) end |
#relations_for_form ⇒ Object
252 253 254 |
# File 'lib/zena/use/relations.rb', line 252 def relations_for_form all_relations.map {|r| [r.other_role.singularize, r.other_role]} end |
#remove_link(link) ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/zena/use/relations.rb', line 184 def remove_link(link) if link[:source_id] != self[:id] && link[:target_id] != self[:id] errors.add('link', "not related to this node") return false end # find proxy if rel = relation_proxy_from_link(link) rel.remove_link(link) else errors.add('link', "cannot remove (relation proxy not found).") end end |