1 (in-package :lisp-on-lines
)
3 ;;;; * Relational Attributes
7 ;;;; Used for foreign keys, currently only works with clsql.
13 :test
'meta-model
::generic-equal
))
16 (define-layered-method attribute-value
(object (attribute has-a
))
17 (meta-model:explode-foreign-key object
(slot-name attribute
) :nilp t
))
19 (define-layered-method (setf attribute-value
) ((value standard-object
) object
(attribute has-a
))
20 (let ((val (slot-value value
(find-if (curry #'primary-key-p value
) (list-keys value
)))))
21 (setf (attribute-value object attribute
) val
)))
25 (define-layered-function find-all-foreign-objects
(o a
))
27 (define-layered-method find-all-foreign-objects
(object (attribute has-a
))
28 (select (meta-model:find-join-class object
(slot-name attribute
)) :flatp t
))
30 (defdisplay ((attribute has-a
) object
)
31 (let ((args (plist-union (description.properties attribute
) (has-a attribute
)))
32 (val (attribute-value object attribute
)))
34 (setf (getf args
:type
)
41 :in-layer editor
((attribute has-a
) object
)
43 :accessor
(attribute-value object attribute
)
45 :test
(test attribute
)
46 (dolist* (obj (find-all-foreign-objects object attribute
))
49 (display* obj
:layers
'(+ as-string
))))))
52 ;;;; ** Has-Many attribute
54 (defattribute has-many
()
57 :add-new-label
"Add New"
58 :sort-arguments
(list #'< :key
#'(lambda (x) (funcall (car (list-keys x
)) x
))))
60 :type
'lol
::one-line
))
62 (define-layered-method
63 attribute-value
(object (has-many has-many
))
64 (slot-value object
(slot-name has-many
)))
66 (defdisplay ((attribute has-many
) object
)
68 ;(<ucw:submit :action (add-to-has-many slot instance) :value (add-new-label attribute))
70 (<:div
:style
"clear:both;"
71 (let* ((i (apply #'sort
(slot-value object
(slot-name attribute
))
72 (sort-arguments attribute
))))
77 :layers
'(+ wrap-link - label-attributes
))))))))
80 (defun find-many-to-many-class (slot-name instance
)
81 (let* ((imd (getf (meta-model::find-slot-metadata instance slot-name
)
83 (jc (make-instance (getf imd
:join-class
)))
84 (jcmd (getf (meta-model::find-slot-metadata jc
(getf imd
:target-slot
))
86 (getf jcmd
:join-class
)))
89 (defattribute many-to-many
()
94 (defdisplay ((attribute many-to-many
) object
)
97 #+nil
(let ((instances (select-instances object t
))
100 (<:li
(<ucw
:button
:action
(add-new-relation component object
(.get slot-name
))
101 (<:as-html
"Add New")))
102 (<:li
(<ucw
:button
:action
(add-new-relation component object new-instance
)
104 (<ucw
:select
:accessor new-instance
105 (arnesi:dolist
* (i instances
)
108 (display component i
:type
'one-line
)))))
109 (dolist* (i (attribute-value object attribute
))
111 (<ucw
:a
:action
(call-view ((car i
) (action-view slot
) (ucw::parent slot
)))
112 (<:as-html
"(view) "))
113 (<ucw
:a
:action
(delete-relationship slot
(second i
) instance
)
114 (<:as-html
"(remove) "))
115 (display component object
)))))
116 ;(display component (mapcar #'car (slot-value object (.get :slot-name))))