Moved to .full in backend, frontend and REST for models.

This commit is contained in:
Martin Edenhofer 2014-08-13 02:12:38 +02:00
parent 7380fa9e9b
commit 8bb4a842a2
19 changed files with 243 additions and 223 deletions

View file

@ -332,7 +332,7 @@ class App.Controller extends Spine.Controller
App.i18n.escape( user.displayName() ) App.i18n.escape( user.displayName() )
content: -> content: ->
user_id = $(@).data('id') user_id = $(@).data('id')
user = App.User.find( user_id ) user = App.User.retrieve( user_id )
# get display data # get display data
data = [] data = []
@ -378,7 +378,7 @@ class App.Controller extends Spine.Controller
App.i18n.escape( organization.name ) App.i18n.escape( organization.name )
content: -> content: ->
organization_id = $(@).data('id') organization_id = $(@).data('id')
organization = App.Organization.find( organization_id ) organization = App.Organization.retrieve( organization_id )
# insert data # insert data
App.view('popover/organization')( App.view('popover/organization')(
organization: organization, organization: organization,

View file

@ -7,11 +7,11 @@ class App.OrganizationZoom extends App.Controller
@navupdate '#' @navupdate '#'
start = (organization) => # subscribe and reload data / fetch new data if triggered
@organization = organization @subscribeId = App.Organization.full( @organization_id, @render, false, true )
@render()
App.Organization.retrieve( @organization_id, start, true ) release: =>
App.Organization.unsubscribe(@subscribeId)
meta: => meta: =>
meta = meta =
@ -34,10 +34,9 @@ class App.OrganizationZoom extends App.Controller
return false if !diff || _.isEmpty( diff ) return false if !diff || _.isEmpty( diff )
return true return true
release: => render: (organization) =>
# nothing @organization = organization
render: =>
# update taskbar with new meta data # update taskbar with new meta data
App.Event.trigger 'task:render' App.Event.trigger 'task:render'

View file

@ -7,11 +7,12 @@ class App.UserZoom extends App.Controller
@navupdate '#' @navupdate '#'
start = (user) => # subscribe and reload data / fetch new data if triggered
@user = user @subscribeId = App.User.full( @user_id, @render, false, true )
@render()
App.User.retrieve( @user_id, start, true )
release: =>
App.User.unsubscribe(@subscribeId)
meta: => meta: =>
meta = meta =
@ -34,10 +35,9 @@ class App.UserZoom extends App.Controller
return false if !diff || _.isEmpty( diff ) return false if !diff || _.isEmpty( diff )
return true return true
release: => render: (user) =>
# nothing @user = user
render: =>
# update taskbar with new meta data # update taskbar with new meta data
App.Event.trigger 'task:render' App.Event.trigger 'task:render'

View file

@ -6,16 +6,8 @@ class App.WidgetOrganization extends App.Controller
constructor: -> constructor: ->
super super
# show organization # subscribe and reload data / fetch new data if triggered
callback = (organization) => @subscribeId = App.Organization.full( @organization_id, @render, false, true )
@render(organization)
if @callback
@callback(organization)
# subscribe and reload data / fetch new data if triggered
@subscribeId = organization.subscribe(@render)
App.Organization.retrieve( @organization_id, callback )
release: => release: =>
App.Organization.unsubscribe(@subscribeId) App.Organization.unsubscribe(@subscribeId)
@ -56,6 +48,9 @@ class App.WidgetOrganization extends App.Controller
) )
@delay( a, 80 ) @delay( a, 80 )
# enable user popups
@userPopups()
### ###
@userTicketPopups( @userTicketPopups(
selector: '.user-tickets' selector: '.user-tickets'
@ -65,7 +60,7 @@ class App.WidgetOrganization extends App.Controller
### ###
update: (e) => update: (e) =>
note = $(e.target).parent().find('[data-type=update]').val() note = $(e.target).val()
organization = App.Organization.find( @organization_id ) organization = App.Organization.find( @organization_id )
if organization.note isnt note if organization.note isnt note
organization.updateAttributes( note: note ) organization.updateAttributes( note: note )

View file

@ -6,16 +6,8 @@ class App.WidgetUser extends App.ControllerDrox
constructor: -> constructor: ->
super super
# show user # subscribe and reload data / fetch new data if triggered
callback = (user) => @subscribeId = App.User.full( @user_id, @render, false, true )
@render(user)
if @callback
@callback(user)
# subscribe and reload data / fetch new data if triggered
@subscribeId = user.subscribe(@render)
App.User.retrieve( @user_id, callback )
release: => release: =>
App.User.unsubscribe(@subscribeId) App.User.unsubscribe(@subscribeId)
@ -41,6 +33,34 @@ class App.WidgetUser extends App.ControllerDrox
if item.info if item.info
userData.push item userData.push item
if user.preferences
items = []
if user.preferences.tickets_open > 0
item =
url: ''
name: 'open'
count: user.preferences.tickets_open
title: 'Open Tickets'
class: 'user-tickets'
data: 'open'
items.push item
if user.preferences.tickets_closed > 0
item =
url: ''
name: 'closed'
count: user.preferences.tickets_closed
title: 'Closed Tickets'
class: 'user-tickets'
data: 'closed'
items.push item
if items[0]
topic =
title: 'Tickets'
items: items
user['links'] = []
user['links'].push topic
# insert userData # insert userData
@html @template( @html @template(
file: 'widget/user' file: 'widget/user'
@ -72,7 +92,7 @@ class App.WidgetUser extends App.ControllerDrox
) )
update: (e) => update: (e) =>
note = $(e.target).parent().find('[data-type=update]').val() note = $(e.target).val()
user = App.User.find( @user_id ) user = App.User.find( @user_id )
if user.note isnt note if user.note isnt note
user.updateAttributes( note: note ) user.updateAttributes( note: note )

View file

@ -79,14 +79,14 @@ class App.Auth
for key, value of data.config for key, value of data.config
App.Config.set( key, value ) App.Config.set( key, value )
# load assets
if data.assets
App.Collection.loadAssets( data.assets )
# refresh default collections # refresh default collections
if data.collections if data.collections
App.Collection.resetCollections( data.collections ) App.Collection.resetCollections( data.collections )
# load assets
if data.assets
App.Collection.loadAssets( data.assets )
# store user data # store user data
session = App.User.retrieve(data.session.id) session = App.User.retrieve(data.session.id)
for key, value of session for key, value of session

View file

@ -117,6 +117,65 @@ class App.Model extends Spine.Model
return true if @id[0] isnt 'c' return true if @id[0] isnt 'c'
return false return false
@full: (id, callback = false, force = false, bind = false) ->
url = "#{@url}/#{id}?full=true"
console.log('FULL', id, url, bind)
# subscribe and reload data / fetch new data if triggered
#@subscribeId = organization.subscribe(@render)
subscribeId = undefined
if bind
subscribeId = App[ @className ].subscribe_item(id, callback)
# execute if object already exists
if !force && App[ @className ].exists( id )
data = App[ @className ].find( id )
data = @_fillUp( data )
if callback
callback( data )
return subscribeId
# store callback and requested id
if !@FULL_CALLBACK
@FULL_CALLBACK = {}
if !@FULL_CALLBACK[id]
@FULL_CALLBACK[id] = {}
if callback
key = @className + '-' + Math.floor( Math.random() * 99999 )
@FULL_CALLBACK[id][key] = callback
if !@FULL_FETCH
@FULL_FETCH = {}
if !@FULL_FETCH[id]
@FULL_FETCH[id] = true
App.Ajax.request(
type: 'GET'
url: url
processData: true,
success: (data, status, xhr) =>
@FULL_FETCH[ data.id ] = false
# full / load assets
if data.assets
App.Collection.loadAssets( data.assets )
# find / load object
else
App[ @className ].refresh( data )
# execute callbacks
if @FULL_CALLBACK[ data.id ]
for key, callback of @FULL_CALLBACK[ data.id ]
callback( @_fillUp( App[ @className ].find( data.id ) ) )
delete @FULL_CALLBACK[ data.id ][ key ]
if _.isEmpty @FULL_CALLBACK[ data.id ]
delete @FULL_CALLBACK[ data.id ]
error: (xhr, statusText, error) =>
console.log(statusText, error)
)
subscribeId
@retrieve: ( id, callback, force ) -> @retrieve: ( id, callback, force ) ->
if !force && App[ @className ].exists( id ) if !force && App[ @className ].exists( id )
data = App[ @className ].find( id ) data = App[ @className ].find( id )
@ -220,42 +279,49 @@ class App.Model extends Spine.Model
subscribe: (callback, type) -> subscribe: (callback, type) ->
# init bind # remember record id and callback
if !App[ @constructor.className ]['SUBSCRIPTION_ITEM'] App[ @constructor.className ].subscribe_item(@id, callback)
App[ @constructor.className ]['SUBSCRIPTION_ITEM'] = {}
@_subscribe_bind: ->
if !@_bindDone
@_bindDone = true
# subscribe and render data after local change # subscribe and render data after local change
App[ @constructor.className ].bind( @bind(
'refresh change' 'refresh change'
(item) => (items) =>
#console.log('BIND', item)
for key, callback of App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ] # check if result is array or singel item
item = App[ @constructor.className ]._fillUp( item ) if !_.isArray(items)
callback(item, 'local') items = [items]
for item in items
for key, callback of App[ @className ].SUBSCRIPTION_ITEM[ item.id ]
item = App[ @className ]._fillUp( item )
callback(item)
) )
# subscribe and render data after server change # subscribe and render data after server change
events = "#{@constructor.className}:create #{@constructor.className}:update #{@constructor.className}:destroy" events = "#{@className}:create #{@className}:update #{@className}:destroy"
App.Event.bind( App.Event.bind(
events events
(item) => (item) =>
#console.log('SERVER BIND try', item) if @SUBSCRIPTION_ITEM && @SUBSCRIPTION_ITEM[ item.id ]
if App[ @constructor.className ]['SUBSCRIPTION_ITEM'] && App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ] @full( item.id, false, true )
#console.log('SERVER BIND', item) 'Item::Subscribe::' + @className
for key, callback of App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ]
callbackRetrieve = (item) ->
callback(item, 'server')
App[ @constructor.className ].retrieve( item.id, callbackRetrieve, true )
'Item::Subscribe::' + @constructor.className
) )
# remember record id and callback @subscribe_item: (id, callback) ->
if !App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ] # init bind
App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ] = {} @_subscribe_bind()
key = @constructor.className + '-' + Math.floor( Math.random() * 99999 )
App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ][key] = callback
# return key # remember item callback
if !@SUBSCRIPTION_ITEM
@SUBSCRIPTION_ITEM = {}
if !@SUBSCRIPTION_ITEM[id]
@SUBSCRIPTION_ITEM[id] = {}
key = @className + '-' + Math.floor( Math.random() * 99999 )
@SUBSCRIPTION_ITEM[id][key] = callback
key key
### ###
@ -266,15 +332,15 @@ class App.Model extends Spine.Model
### ###
@unsubscribe: (data) -> @unsubscribe: (subscribeId) ->
if @SUBSCRIPTION_ITEM if @SUBSCRIPTION_ITEM
for id, keys of @SUBSCRIPTION_ITEM for id, keys of @SUBSCRIPTION_ITEM
if keys[data] if keys[subscribeId]
delete keys[data] delete keys[subscribeId]
if @SUBSCRIPTION_COLLECTION if @SUBSCRIPTION_COLLECTION
if @SUBSCRIPTION_COLLECTION[data] if @SUBSCRIPTION_COLLECTION[subscribeId]
delete @SUBSCRIPTION_COLLECTION[data] delete @SUBSCRIPTION_COLLECTION[subscribeId]
@_bindsEmpty: -> @_bindsEmpty: ->
if @SUBSCRIPTION_ITEM if @SUBSCRIPTION_ITEM

View file

@ -20,10 +20,10 @@ class App.Organization extends App.Model
@_fillUp: (data) -> @_fillUp: (data) ->
# addd users of organization # addd users of organization
if data['user_ids'] if data['member_ids']
data['user_ids'] = [] data['members'] = []
for user_id in data['user_ids'] for user_id in data['member_ids']
if App.User.exists( user_id ) if App.User.exists( user_id )
user = App.User.find( user_id ) user = App.User.find( user_id )
data['user_ids'].push user data['members'].push user
data data

View file

@ -1 +0,0 @@
<div class="user_info"></div>

View file

@ -21,6 +21,15 @@
<% end %> <% end %>
<% end %> <% end %>
<% if @organization.members: %>
<h4><%- @T('Member') %></h4>
<ul>
<% for user in @organization.members: %>
<li><a href="<%- user.uiUrl() %>" class="user-popover" data-id="<%- user.id %>"><%= user.displayName() %></a></li>
<% end %>
</ul>
<% end %>
</div> </div>
</div> </div>

View file

@ -76,6 +76,7 @@ class ApplicationController < ActionController::Base
# update session updated_at # update session updated_at
def session_update def session_update
#sleep 0.6
# on many paralell requests, session got reinitialised if Time. is used, as workaround use DateTime. # on many paralell requests, session got reinitialised if Time. is used, as workaround use DateTime.
#session[:ping] = Time.now.utc.iso8601 #session[:ping] = Time.now.utc.iso8601
@ -317,6 +318,13 @@ class ApplicationController < ActionController::Base
def model_show_render (object, params) def model_show_render (object, params)
begin begin
if params[:full]
generic_object_full = object.full( params[:id] )
render :json => generic_object_full, :status => :ok
return
end
generic_object = object.find( params[:id] ) generic_object = object.find( params[:id] )
model_show_render_item(generic_object) model_show_render_item(generic_object)
rescue Exception => e rescue Exception => e

View file

@ -90,6 +90,11 @@ curl http://localhost/api/v1/organizations/#{id}.json -v -u #{login}:#{password}
return return
end end
end end
if params[:full]
full = Organization.full( params[:id] )
render :json => full
return
end
model_show_render(Organization, params) model_show_render(Organization, params)
end end

View file

@ -4,30 +4,30 @@ module ExtraCollection
def session( collections, assets, user ) def session( collections, assets, user )
# all base stuff # all base stuff
collections[ Taskbar.to_app_model ] = Taskbar.where( :user_id => user.id )
assets = {} assets = {}
collections[ Taskbar.to_app_model ] = Taskbar.where( :user_id => user.id )
collections[ Taskbar.to_app_model ].each {|item| collections[ Taskbar.to_app_model ].each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
collections[ Role.to_app_model ] = Role.all collections[ Role.to_app_model ] = []
collections[ Role.to_app_model ].each {|item| Role.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
collections[ Group.to_app_model ] = Group.all collections[ Group.to_app_model ] = []
collections[ Group.to_app_model ].each {|item| Group.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
if !user.is_role('Customer') if !user.is_role('Customer')
collections[ Organization.to_app_model ] = Organization.all collections[ Organization.to_app_model ] = []
collections[ Organization.to_app_model ].each {|item| Organization.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
else else
if user.organization_id if user.organization_id
collections[ Organization.to_app_model ] = Organization.where( :id => user.organization_id ) collections[ Organization.to_app_model ] = []
collections[ Organization.to_app_model ].each {|item| Organization.where( :id => user.organization_id ).each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
end end

View file

@ -4,37 +4,37 @@ module ExtraCollection
def session( collections, assets, user ) def session( collections, assets, user )
# all ticket stuff # all ticket stuff
collections[ Ticket::StateType.to_app_model ] = Ticket::StateType.all collections[ Ticket::StateType.to_app_model ] = []
collections[ Ticket::StateType.to_app_model ].each {|item| Ticket::StateType.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
collections[ Ticket::State.to_app_model ] = Ticket::State.all collections[ Ticket::State.to_app_model ] = []
collections[ Ticket::State.to_app_model ].each {|item| Ticket::State.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
collections[ Ticket::Priority.to_app_model ] = Ticket::Priority.all collections[ Ticket::Priority.to_app_model ] = []
collections[ Ticket::Priority.to_app_model ].each {|item| Ticket::Priority.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
collections[ Ticket::Article::Type.to_app_model ] = Ticket::Article::Type.all collections[ Ticket::Article::Type.to_app_model ] = []
collections[ Ticket::Article::Type.to_app_model ].each {|item| Ticket::Article::Type.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
collections[ Ticket::Article::Sender.to_app_model ] = Ticket::Article::Sender.all collections[ Ticket::Article::Sender.to_app_model ] = []
collections[ Ticket::Article::Sender.to_app_model ].each {|item| Ticket::Article::Sender.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
if !user.is_role('Customer') if !user.is_role('Customer')
# all signatures # all signatures
collections[ Signature.to_app_model ] = Signature.all collections[ Signature.to_app_model ] = []
collections[ Signature.to_app_model ].each {|item| Signature.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
# all email addresses # all email addresses
collections[ EmailAddress.to_app_model ] = EmailAddress.all collections[ EmailAddress.to_app_model ] = []
collections[ EmailAddress.to_app_model ].each {|item| EmailAddress.all.each {|item|
assets = item.assets(assets) assets = item.assets(assets)
} }
end end

View file

@ -262,23 +262,20 @@ class TicketsController < ApplicationController
# get related users # get related users
assets = {} assets = {}
assets[ User.to_app_model ] = {}
assets = ticket.assets(assets) assets = ticket.assets(assets)
# get attributes to update # get attributes to update
attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket ) attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket )
attributes_to_change[:owner_id].each { |user_id| attributes_to_change[:owner_id].each { |user_id|
if !assets[ User.to_app_model ][user_id] user = User.find(user_id)
assets[ User.to_app_model ][user_id] = User.user_data_full( user_id ) assets = user.assets(assets)
end
} }
attributes_to_change[:group_id__owner_id].each {|group_id, user_ids| attributes_to_change[:group_id__owner_id].each {|group_id, user_ids|
user_ids.each {|user_id| user_ids.each {|user_id|
if !assets[ User.to_app_model ][user_id] user = User.find(user_id)
assets[ User.to_app_model ][user_id] = User.user_data_full( user_id ) assets = user.assets(assets)
end
} }
} }
@ -322,16 +319,14 @@ class TicketsController < ApplicationController
assets = {} assets = {}
assets[ User.to_app_model ] = {} assets[ User.to_app_model ] = {}
attributes_to_change[:owner_id].each { |user_id| attributes_to_change[:owner_id].each { |user_id|
if !assets[ User.to_app_model ][user_id] user = User.find(user_id)
assets[ User.to_app_model ][user_id] = User.user_data_full( user_id ) assets = user.assets(assets)
end
} }
attributes_to_change[:group_id__owner_id].each {|group_id, user_ids| attributes_to_change[:group_id__owner_id].each {|group_id, user_ids|
user_ids.each {|user_id| user_ids.each {|user_id|
if !assets[ User.to_app_model ][user_id] user = User.find(user_id)
assets[ User.to_app_model ][user_id] = User.user_data_full( user_id ) assets = user.assets(assets)
end
} }
} }
@ -345,9 +340,7 @@ class TicketsController < ApplicationController
owner_ids = [] owner_ids = []
ticket.agent_of_group.each { |user| ticket.agent_of_group.each { |user|
owner_ids.push user.id owner_ids.push user.id
if !assets[ User.to_app_model ][user.id] assets = user.assets(assets)
assets[ User.to_app_model ][user.id] = User.user_data_full( user.id )
end
} }
# get related articles # get related articles

View file

@ -70,7 +70,7 @@ curl http://localhost/api/v1/users.json -v -u #{login}:#{password}
end end
users_all = [] users_all = []
users.each {|user| users.each {|user|
users_all.push User.user_data_full( user.id ) users_all.push User.find( user.id )
} }
render :json => users_all, :status => :ok render :json => users_all, :status => :ok
end end
@ -101,7 +101,14 @@ curl http://localhost/api/v1/users/#{id}.json -v -u #{login}:#{password}
return return
end end
end end
user = User.user_data_full( params[:id] )
if params[:full]
full = User.full( params[:id] )
render :json => full
return
end
user = User.find( params[:id] )
render :json => user render :json => user
end end
@ -245,7 +252,7 @@ curl http://localhost/api/v1/users.json -v -u #{login}:#{password} -H "Content-T
) )
end end
user_new = User.user_data_full( user.id ) user_new = User.find( user.id )
render :json => user_new, :status => :created render :json => user_new, :status => :created
rescue Exception => e rescue Exception => e
render :json => { :error => e.message }, :status => :unprocessable_entity render :json => { :error => e.message }, :status => :unprocessable_entity
@ -309,7 +316,7 @@ curl http://localhost/api/v1/users/2.json -v -u #{login}:#{password} -H "Content
end end
# get new data # get new data
user_new = User.user_data_full( params[:id] ) user_new = User.find( params[:id] )
render :json => user_new, :status => :ok render :json => user_new, :status => :ok
rescue Exception => e rescue Exception => e
render :json => { :error => e.message }, :status => :unprocessable_entity render :json => { :error => e.message }, :status => :unprocessable_entity

View file

@ -883,4 +883,25 @@ destory object dependencies, will be executed automatically
def destroy_dependencies def destroy_dependencies
end end
=begin
return object and assets
data = Model.full(123)
data = {
:id => 123,
:assets => assets,
}
=end
def self.full(id)
object = self.find(id)
assets = object.assets({})
{
:id => id,
:assets => assets,
}
end
end end

View file

@ -361,108 +361,6 @@ returns
return user return user
end end
def self.find_fulldata(user_id)
cache = self.cache_get(user_id, true)
return cache if cache
# get user
user = User.find(user_id)
data = user.attributes
# do not show password
user['password'] = ''
# get linked accounts
data['accounts'] = {}
authorizations = user.authorizations() || []
authorizations.each do | authorization |
data['accounts'][authorization.provider] = {
:uid => authorization[:uid],
:username => authorization[:username]
}
end
# set roles
roles = []
user.roles.select('id, name').where( :active => true ).each { |role|
roles.push role.attributes
}
data['roles'] = roles
data['role_ids'] = user.role_ids
groups = []
user.groups.select('id, name').where( :active => true ).each { |group|
groups.push group.attributes
}
data['groups'] = groups
data['group_ids'] = user.group_ids
organization = user.organization
if organization
data['organization'] = organization.attributes
end
organizations = []
user.organizations.select('id, name').where( :active => true ).each { |organization|
organizations.push organization.attributes
}
data['organizations'] = organizations
data['organization_ids'] = user.organization_ids
self.cache_set(user.id, data, true)
return data
end
def self.user_data_full (user_id)
# get user
user = User.find_fulldata(user_id)
# do not show password
user['password'] = ''
# TEMP: compat. reasons
user['preferences'] = {} if user['preferences'] == nil
items = []
if user['preferences'][:tickets_open].to_i > 0
item = {
:url => '',
:name => 'open',
:count => user['preferences'][:tickets_open] || 0,
:title => 'Open Tickets',
:class => 'user-tickets',
:data => 'open'
}
items.push item
end
if user['preferences'][:tickets_closed].to_i > 0
item = {
:url => '',
:name => 'closed',
:count => user['preferences'][:tickets_closed] || 0,
:title => 'Closed Tickets',
:class => 'user-tickets',
:data => 'closed'
}
items.push item
end
# show linked topics and items
if items.count > 0
topic = {
:title => 'Tickets',
:items => items,
}
user['links'] = []
user['links'].push topic
end
return user
end
=begin =begin
update last login date and reset login_failed (is automatically done by auth and sso backend) update last login date and reset login_failed (is automatically done by auth and sso backend)

View file

@ -45,7 +45,7 @@ class Sessions::Backend::TicketCreate
users = {} users = {}
create_attributes[:owner_id].each {|user_id| create_attributes[:owner_id].each {|user_id|
if !users[user_id] if !users[user_id]
users[user_id] = User.user_data_full(user_id) users[user_id] = User.find(user_id).attributes
end end
} }
data = { data = {