| Class | PeopleController |
| In: |
app/controllers/people_controller.rb
|
| Parent: | ApplicationController |
Controller for the Person class.
# File app/controllers/people_controller.rb, line 277
277: def add_name
278: @person = Person.find(params[:id])
279: @name = Name.new(params[:name])
280: begin
281: if @person.names<< @name
282: flash.now[:notice] = 'New name was successfully added.'
283: render :inline => "<%= remote_link_to_add_with_update( @person, 'name', {:name => 'name', :partial => 'names/object_names', :object_as => 'object'} ) %>"
284: else
285: throw 'Problem adding that name'
286: end
287: rescue
288: flash.now[:warning] = 'That name could not be added.'
289: render :inline => "<%= remote_form_add_new @person, @name %>"
290: end
291: end
# File app/controllers/people_controller.rb, line 30
30: def auto_complete_for_person_clan
31: @names = Clan.names_like( params[:clan][:name] )
32: render :inline => "<%= auto_complete_result(@names, 'name') %>"
33: end
This action provides a list of names for any name field in the view, i.e. not just
text_field_with_auto_complete :person, :name
For example, the following would also work:
text_field_with_auto_complete :contributor, :name, {}, {:url => {:controller => :people, :action => 'auto_complete_for_person_name' }}
For this to work the object can be called anything, but the method must be name.
# File app/controllers/people_controller.rb, line 14
14: def auto_complete_for_person_name
15: # This expression finds the _"name"_ key of the first (should be only) key in
16: # params that has one. Including:
17: # {"contributor"=>{"name"=>"Bob"}}
18: # {"person"=>{"name"=>"Bob"}}
19: params.values.each do |value|
20: if value.is_a?( Hash ) && value.include?("name")
21: @name = value["name"]
22: break
23: end
24: end
25:
26: @people = Person.find_by_contents("name_list:#{@name}*")
27: render :inline => "<%= auto_complete_result(@people, 'primary_names', @name) %>"
28: end
# File app/controllers/people_controller.rb, line 35
35: def auto_complete_for_surname_name
36: @surnames = Name.find(:all,
37: :conditions => [ "name_type = 'surname' AND in_use = true AND LOWER(name) LIKE ?",
38: params[:surname][:name].downcase + '%' ])
39: render :inline => "<%= auto_complete_result(@surnames, 'name') %>"
40: end
# File app/controllers/people_controller.rb, line 174
174: def create
175: person_clan = params[:person].delete(:clan) # remove [:person][:clan]
176: @person = Person.new(params[:person])
177:
178: begin
179: # person must have a first name
180: @name = Name.new(params[:name])
181: @person.names<< @name
182:
183: # person may have a clan
184: unless person_clan.blank?
185: clan_name = Name.find(:first, :conditions => [ "object_type = 'Clan' AND LOWER(name) = ?", person_clan.downcase])
186: if clan_name
187: @clan = clan_name.object
188: @person.clan = @clan
189: else
190: @person.errors.add(:clan, """ + person_clan + "" could not be found in the database")
191: raise
192: end
193: end
194:
195: # person may have a surname
196: unless params[:surname][:name].blank?
197: @surname = Name.find(:first, :conditions => [ "name_type = 'surname' AND LOWER(name) = ?", params[:surname][:name].downcase])
198: unless @surname
199: @surname = Name.new(params[:surname])
200: @surname.object_type = 'Person'
201: end
202: @person.surname = @surname
203: end
204:
205: @person.save! # will throw an exception if save fails
206:
207: respond_to do |format|
208: format.html do
209: flash[:notice] = 'Person was successfully created.'
210: redirect_to :action => 'index'
211: end
212: format.js do
213: render :update do |page|
214: replace 'person_form', "Person created"
215: end
216: end
217: end
218: rescue => e
219: flash[:warning] = "There was a problem with creating the new person. #{e.message}"
220: render :action => 'new'
221: end
222: end
# File app/controllers/people_controller.rb, line 293
293: def destroy
294: Person.find(params[:id]).destroy
295: redirect_to :action => 'index'
296: end
# File app/controllers/people_controller.rb, line 224
224: def edit
225: @person = Person.find(params[:id], :include => :names)
226: end
# File app/controllers/people_controller.rb, line 66
66: def index
67: list
68: render :action => 'list'
69: end
# File app/controllers/people_controller.rb, line 81
81: def list
82: if params['clan']
83: if params['clan'].to_i != 0
84: clan_condition = "people.clan_id = " + params['clan']
85: elsif params['clan'] == 'none'
86: clan_condition = 'people.clan_id IS null'
87: end
88: count = Person.count(:conditions => clan_condition)
89: else
90: count = Person.count
91: end
92:
93: # @person_pages, @people = paginate :people, :per_page => 100, :order => 'clan_id, date_of_birth'
94:
95: @person_pages = Paginator.new self, count, 100, params['page']
96:
97: # Find all people, sorted by last name, then first name. In the query first_name refers to
98: # the name which is alphabetically first (of the names which are nor surnames).
99: find_params = {
100: :select => "people.*, (SELECT UPPER(MIN(names.name)) FROM names
101: WHERE names.object_id = people.id AND names.object_type = 'Person' AND names.name_type != 'surname' AND names.in_use = true AND names.primary_name = true
102: GROUP BY names.object_id) AS first_name,
103: (SELECT UPPER(MIN(names.name)) FROM names
104: WHERE names.id = people.surname_id) AS last_name",
105: :order => "last_name, first_name",
106: :limit => @person_pages.items_per_page,
107: :offset => @person_pages.current.offset
108: }
109:
110: find_params = find_params.merge({ :conditions => clan_condition }) if clan_condition
111:
112:
113: # This query does not include names, so the database is hit again for names. Normally this would be done using
114: # Person.find(:all, :include => "names")
115: # which would produces the following query:
116: # SELECT people."id" AS t0_r0, people."sex" AS t0_r1, people."language_id" AS t0_r2,
117: # people."date_of_birth" AS t0_r3, people."date_of_death" AS t0_r4, people."description" AS t0_r5,
118: # people."clan_id" AS t0_r6, people."surname_id" AS t0_r7, people."restriction" AS t0_r8, names."id" AS t1_r0,
119: # names."name" AS t1_r1, names."object_type" AS t1_r2, names."language_id" AS t1_r3, names."in_use" AS t1_r4,
120: # names."name_type" AS t1_r5, names."notes" AS t1_r6, names."primary_name" AS t1_r7, names."object_id" AS t1_r8
121: # FROM people LEFT OUTER JOIN names ON names.object_id = people.id AND names.object_type = 'Person'
122: #
123: # In order to avoid the N+1 queries for people's names we would have to emulate that somehow, or change
124: # the data model.
125: @people = Person.find(:all, find_params)
126:
127: # new person for search
128: # @person = Person.new
129: respond_to do |format|
130: format.html {
131: @people = Person.find(:all, find_params)
132: }
133: format.xml {
134: @people = Person.find(:all)
135: render :action => "list.rxml", :layout => false, :content_type => 'text/xml'
136: }
137: end
138: end
# File app/controllers/people_controller.rb, line 71
71: def list_clans
72: # might be able to figure out a way to save on query cost by using something like
73: # :include => :names, :conditions => "names.in_use = true AND names.primary_name = true AND (names.name_type='traditional' OR names.name_type='surname')"
74: @clans = Clan.find(:all, :order => "clans.moiety, clans.id", :include => :names)
75: end
# File app/controllers/people_controller.rb, line 162
162: def new
163: @person = Person.new
164: @name = Name.new
165: @clan_name = Name.new
166: @surname = Name.new
167:
168: respond_to do |format|
169: format.html
170: format.js { render :partial => 'new', :layout => false } # won't be that good because it needs to have a different form action (or have a switch in the view?)
171: end
172: end
# File app/controllers/people_controller.rb, line 271
271: def new_name
272: @person = Person.find(params[:id])
273: @name = Name.new
274: render :inline => "<%= remote_form_add_new @person, @name %>"
275: end
Searches the database for people using ferret (find_by_contents) and then renders the results in the normal list action.
# File app/controllers/people_controller.rb, line 142
142: def search
143: total_hits, results = Person.find_id_by_contents(params[:person][:name])
144: if total_hits == 1
145: flash[:notice] = "Only one person matching the search \"" + params[:person][:name] + "\"."
146: redirect_to :action => 'show', :id => results.first[:id].to_s
147: else
148: @person_pages, @people = paginate_collection Person.find_by_contents(params[:person][:name]), :per_page => 50, :page => params[:page]
149: flash[:notice] = total_hits.to_s + " people matching the search \"" + params[:person][:name] + "\"."
150: render :action => 'list'
151: end
152: end
# File app/controllers/people_controller.rb, line 154
154: def show
155: @person = Person.find(params[:id]) rescue nil
156:
157: unless @person
158: redirect_to :action => 'index'
159: end
160: end
# File app/controllers/people_controller.rb, line 228
228: def update
229: @person = Person.find(params[:id])
230:
231: # clan may be updated
232: if params[:clan][:name] && !params[:clan][:name].empty?
233: clan_name = Name.find(:first, :conditions => [ "object_type = 'Clan' AND LOWER(name) = ?", params[:clan][:name].downcase])
234: if clan_name
235: @clan = clan_name.object
236: else
237: @clan = Clan.new
238: @clan.errors.add_to_base("The clan "" + params[:clan][:name] + "" could not be found in the database")
239: end
240: @person.clan = @clan
241: elsif params[:clan][:name].empty?
242: @person.clan_id = nil
243: end
244:
245: # surname may be updated
246: if params[:surname][:name] && params[:surname][:name] != ""
247: @surname = Name.find(:first, :conditions => [ "name_type = 'surname' AND LOWER(name) = ?", params[:surname][:name].downcase])
248: unless @surname
249: @surname = Name.create(params[:surname])
250: end
251: @person.surname = @surname unless @person.surname_id == @surname.id
252: end
253:
254: message = nil
255: begin
256: raise ActiveRecord::ActiveRecordError, message if message
257:
258: @person.update_attributes!(params[:person]) # will throw an exception if save fails
259: rescue ActiveRecord::MultiparameterAssignmentErrors => e
260: message = "Invalid " + (e.errors.map {|error| error.attribute.titleize}).join(", ")
261: retry
262: rescue => e
263: flash[:warning] = "There was a problem with creating the new person. #{e.message}"
264: render :action => 'edit'
265: else
266: flash[:notice] = 'Person was successfully updated.'
267: redirect_to :action => 'show', :id => @person
268: end
269: end
This method is used to dynamically update the surname field according to the clan affiliation of a person who is being created or edited.
# File app/controllers/people_controller.rb, line 44
44: def update_surname
45: # Find name that matches the clan input
46: name = Name.find(:first,
47: :conditions => [ "object_type = 'Clan' AND LOWER(name) = ?", params[:value].downcase ])
48:
49: # If the clan name is aready a surname use it, otherwise find a surname that matches this clan name.
50: if name.name_type == 'surname'
51: @surname = name
52: else
53: @surname = Name.find(:first,
54: :conditions => ["name_type = 'surname' AND object_type = 'Clan' AND object_id = ?", name.object.id],
55: :order => 'primary_name, in_use')
56: end
57:
58: # Render name into surname input box if there is a candidate.
59: if @surname
60: render :text => @surname.name
61: else
62: render :nothing => true
63: end
64: end