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
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 356 |
# File 'lib/zena/use/relations.rb', line 312 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’
153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/zena/use/relations.rb', line 153 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
255 256 257 |
# File 'lib/zena/use/relations.rb', line 255 def all_relations @all_relations ||= self.vclass.all_relations(self) end |
#l_comment ⇒ Object
comment defined through loading link
136 137 138 139 |
# File 'lib/zena/use/relations.rb', line 136 def l_comment return @l_comment if defined? @l_comment @link ? @link[:comment] : self['l_comment'] end |
#l_comment=(v) ⇒ Object
211 212 213 214 215 216 217 218 219 |
# File 'lib/zena/use/relations.rb', line 211 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
142 143 144 145 |
# File 'lib/zena/use/relations.rb', line 142 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
231 232 233 234 235 236 237 238 239 |
# File 'lib/zena/use/relations.rb', line 231 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
127 128 129 130 131 |
# File 'lib/zena/use/relations.rb', line 127 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
221 222 223 224 225 226 227 228 229 |
# File 'lib/zena/use/relations.rb', line 221 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
147 148 149 |
# File 'lib/zena/use/relations.rb', line 147 def link_id @link ? @link[:id] : (self[:link_id] == -1 ? nil : self[:link_id]) # -1 == dummy link end |
#link_id=(v) ⇒ Object
241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/zena/use/relations.rb', line 241 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
122 123 124 |
# File 'lib/zena/use/relations.rb', line 122 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”.
118 119 120 |
# File 'lib/zena/use/relations.rb', line 118 def linked_node=(node) @linked_node = node end |
#rel ⇒ Object
201 202 203 |
# File 'lib/zena/use/relations.rb', line 201 def rel ProxyLoader.new(self) end |
#rel=(hash) ⇒ Object
This accessor is used when the data arrives with the syntax rel => { friend => … }
207 208 209 |
# File 'lib/zena/use/relations.rb', line 207 def rel=(hash) self.rel_attributes = hash end |
#rel_attributes=(hash) ⇒ Object
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/zena/use/relations.rb', line 181 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 113 |
# File 'lib/zena/use/relations.rb', line 96 def relation_alias(match) return nil if respond_to?("#{match[0]}=") # native method 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
264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/zena/use/relations.rb', line 264 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.
277 278 279 280 281 |
# File 'lib/zena/use/relations.rb', line 277 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
283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/zena/use/relations.rb', line 283 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
259 260 261 |
# File 'lib/zena/use/relations.rb', line 259 def relations_for_form all_relations.map {|r| [r.other_role.singularize, r.other_role]} end |
#remove_link(link) ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/zena/use/relations.rb', line 168 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 |