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 (multiple-value-bind (obj key class
)
18 (meta-model:explode-foreign-key object
(slot-name attribute
) :nilp t
)
19 (if (persistentp object
)
22 :where
[= [slot-value class key
] (call-next-method)]
26 (define-layered-method (setf attribute-value
) ((value standard-object
) object
(attribute has-a
))
27 (let ((val (slot-value value
(find-if (curry #'primary-key-p value
) (list-keys value
)))))
28 (setf (attribute-value object attribute
) val
)))
32 (define-layered-function find-all-foreign-objects
(o a
))
34 (define-layered-method find-all-foreign-objects
(object (attribute has-a
))
35 (select (meta-model:find-join-class object
(slot-name attribute
)) :flatp t
))
37 (defdisplay ((attribute has-a
) object
)
38 (let ((args (plist-union (description.properties attribute
) (has-a attribute
)))
39 (val (attribute-value object attribute
)))
41 (setf (getf args
:type
)
48 :in-layer editor
((attribute has-a
) object
)
50 :accessor
(attribute-value object attribute
)
52 :test
(test attribute
)
53 (dolist* (obj (find-all-foreign-objects object attribute
))
56 (display* obj
:layers
'(+ as-string
))))))
59 ;;;; ** Has-Many attribute
61 (defattribute has-many
()
64 :add-new-label
"Add New"
65 :sort-arguments
(list #'< :key
#'(lambda (x) (funcall (car (list-keys x
)) x
))))
67 :type
'lol
::one-line
))
69 (define-layered-method
70 attribute-value
(object (has-many has-many
))
71 (slot-value object
(slot-name has-many
)))
73 (defdisplay ((attribute has-many
) object
)
75 ;(<ucw:submit :action (add-to-has-many slot instance) :value (add-new-label attribute))
77 (<:div
:style
"clear:both;"
78 (let* ((i (apply #'sort
(slot-value object
(slot-name attribute
))
79 (sort-arguments attribute
))))
84 :layers
'(+ wrap-link - label-attributes
))))))))
87 (defun find-many-to-many-class (slot-name instance
)
88 (let* ((imd (getf (meta-model::find-slot-metadata instance slot-name
)
90 (jc (make-instance (getf imd
:join-class
)))
91 (jcmd (getf (meta-model::find-slot-metadata jc
(getf imd
:target-slot
))
93 (getf jcmd
:join-class
)))
96 (defattribute many-to-many
()
101 (defdisplay ((attribute many-to-many
) object
)
102 (<:as-html
"ASDASD"))
104 #+nil
(let ((instances (select-instances object t
))
107 (<:li
(<ucw
:button
:action
(add-new-relation component object
(.get slot-name
))
108 (<:as-html
"Add New")))
109 (<:li
(<ucw
:button
:action
(add-new-relation component object new-instance
)
111 (<ucw
:select
:accessor new-instance
112 (arnesi:dolist
* (i instances
)
115 (display component i
:type
'one-line
)))))
116 (dolist* (i (attribute-value object attribute
))
118 (<ucw
:a
:action
(call-view ((car i
) (action-view slot
) (ucw::parent slot
)))
119 (<:as-html
"(view) "))
120 (<ucw
:a
:action
(delete-relationship slot
(second i
) instance
)
121 (<:as-html
"(remove) "))
122 (display component object
)))))
123 ;(display component (mapcar #'car (slot-value object (.get :slot-name))))