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
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 350 351 352 353 354 355 |
# File 'lib/zena/use/relations.rb', line 311 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
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/zena/use/relations.rb', line 67 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’
152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/zena/use/relations.rb', line 152 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
254 255 256 |
# File 'lib/zena/use/relations.rb', line 254 def all_relations @all_relations ||= self.vclass.all_relations(self) end |
#l_comment ⇒ Object
comment defined through loading link
135 136 137 138 |
# File 'lib/zena/use/relations.rb', line 135 def l_comment return @l_comment if defined? @l_comment @link ? @link[:comment] : self['l_comment'] end |
#l_comment=(v) ⇒ Object
210 211 212 213 214 215 216 217 218 |
# File 'lib/zena/use/relations.rb', line 210 def l_comment=(v) @l_comment = v.blank? ? nil : v if rel = relation_proxy_from_link rel.other_comment = @l_comment else l = @link_attributes_to_update ||= {} l[:comment] = @l_comment end end |
#l_date ⇒ Object
date defined through loading link
141 142 143 144 |
# File 'lib/zena/use/relations.rb', line 141 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
230 231 232 233 234 235 236 237 238 |
# File 'lib/zena/use/relations.rb', line 230 def l_date=(v) @l_date = v.blank? ? nil : v if rel = relation_proxy_from_link rel.other_date = @l_date else l = @link_attributes_to_update ||= {} l[:date] = @l_date end end |
#l_status ⇒ Object
status defined through loading link
126 127 128 129 130 |
# File 'lib/zena/use/relations.rb', line 126 def l_status return @l_status if defined? @l_status val = @link ? @link[:status] : self['l_status'] val ? val.to_f : nil end |
#l_status=(v) ⇒ Object
220 221 222 223 224 225 226 227 228 |
# File 'lib/zena/use/relations.rb', line 220 def l_status=(v) @l_status = v.blank? ? nil : v if rel = relation_proxy_from_link rel.other_status = @l_status else l = @link_attributes_to_update ||= {} l[:status] = @l_status end end |
#link_id ⇒ Object
146 147 148 |
# File 'lib/zena/use/relations.rb', line 146 def link_id @link ? @link[:id] : (self[:link_id] == -1 ? nil : self[:link_id]) # -1 == dummy link end |
#link_id=(v) ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/zena/use/relations.rb', line 240 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
121 122 123 |
# File 'lib/zena/use/relations.rb', line 121 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”.
117 118 119 |
# File 'lib/zena/use/relations.rb', line 117 def linked_node=(node) @linked_node = node end |
#rel ⇒ Object
200 201 202 |
# File 'lib/zena/use/relations.rb', line 200 def rel ProxyLoader.new(self) end |
#rel=(hash) ⇒ Object
This accessor is used when the data arrives with the syntax rel => { friend => … }
206 207 208 |
# File 'lib/zena/use/relations.rb', line 206 def rel=(hash) self.rel_attributes = hash end |
#rel_attributes=(hash) ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/zena/use/relations.rb', line 180 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.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/zena/use/relations.rb', line 96 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
263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/zena/use/relations.rb', line 263 def relation_links res = [] all_relations.each do |rel| #if relation.record_count > 5 # # FIXME: show message ? #end links = rel.records(:limit => 25, :order => "link_id DESC") res << [rel, links] if links end res end |
#relation_proxy(role) ⇒ Object
Find relation proxy for the given role.
276 277 278 279 280 |
# File 'lib/zena/use/relations.rb', line 276 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
282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/zena/use/relations.rb', line 282 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
258 259 260 |
# File 'lib/zena/use/relations.rb', line 258 def relations_for_form all_relations.map {|r| [r.other_role.singularize, r.other_role]} end |
#remove_link(link) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/zena/use/relations.rb', line 167 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 |