Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 428
- Log:
Canvass was converting e-mail addresses to lower case
when it saved User details for some reason. This meant
that any Hub user with a mixed-case e-mail address would
be able to access one page from Canvass, then nothing
else; Canvass would fail to find a matching local user
with their Hub-based mixed case address, create a new
user, save it and in saving convert the address to
lower case and thus encounter an exception as a local
user would already exist with the lower case version of
the mixed case address.Very simple fix; verified by checking access to Canvass
on the ROOL site using a mixed case e-mail address in a
Hub account.
- Author:
- rool
- Date:
- Sun Oct 30 14:53:47 +0000 2011
- Size:
- 5032 Bytes
1 | ######################################################################## |
2 | # File:: user.rb |
3 | # (C):: Hipposoft 2011 |
4 | # |
5 | # Purpose:: Descriptions of users, cached from Hub information. |
6 | # ---------------------------------------------------------------------- |
7 | # 30-Jan-2011 (ADH): Created. |
8 | ######################################################################## |
9 | |
10 | class User < ActiveRecord::Base |
11 | |
12 | # =========================================================================== |
13 | # CHARACTERISTICS |
14 | # =========================================================================== |
15 | |
16 | serialize :preferences |
17 | |
18 | has_many :polls |
19 | has_many :donations |
20 | |
21 | MAXLEN_NAME = 150 |
22 | MAXLEN_EMAIL = 200 |
23 | |
24 | validates_presence_of :name |
25 | validates_length_of :name, :within => 1..MAXLEN_NAME |
26 | |
27 | validates_presence_of :email |
28 | validates_uniqueness_of :email |
29 | validates_length_of :email, :within => 6..MAXLEN_EMAIL # 6 => "r@a.wk" |
30 | |
31 | # Almost nothing is accessible to mass assignment. |
32 | |
33 | attr_accessible( |
34 | :name |
35 | ) |
36 | |
37 | # See Jason King's "good_sort" plugin: |
38 | # |
39 | # http://github.com/JasonKing/good_sort/tree/master |
40 | # |
41 | # Must use "table_exists?", as good_sort needs to check the database but |
42 | # this class may be examined by migrations before the table is created. |
43 | |
44 | sort_on :name, |
45 | :email, |
46 | :admin if User.table_exists? |
47 | |
48 | # How many entries to list per index page? See the Will Paginate plugin: |
49 | # |
50 | # http://wiki.github.com/mislav/will_paginate |
51 | # |
52 | def self.per_page |
53 | MAXIMUM_LIST_ITEMS_PER_PAGE |
54 | end |
55 | |
56 | # Search columns for views rendering the "shared/_simple_search.html.erb" |
57 | # view partial and using "appctrl_build_search_conditions" to handle queries. |
58 | |
59 | SEARCH_COLUMNS = %w{name email} |
60 | |
61 | # =========================================================================== |
62 | # GENERAL |
63 | # =========================================================================== |
64 | |
65 | # Apply a default sort to the given array of model instances. The array is |
66 | # modified in place. |
67 | # |
68 | def self.apply_default_sort_order( array ) |
69 | array.sort! { | x, y | x.name <=> y.name } |
70 | end |
71 | |
72 | # Get a value from the user's preferences hash. The hash is nested in a |
73 | # similar manner to the I18n module's translation hashes and is addressed |
74 | # in a similar way - pass a dot-separated key string, e.g. "foo.bar.baz". |
75 | # Returns 'nil' for unset preferences, else the value at that location. |
76 | # |
77 | # Currently defined preferences include (but may not be limited to - this |
78 | # list may be out of date) the following: |
79 | # |
80 | # sorting => { <controller-name> => { <good_sort params hash entry> } } |
81 | # |
82 | # Most recently recorded value of params[:sort] by an index action for |
83 | # a controller identified by <controller_name>. For more information see |
84 | # "appctrl_apply_sorting_preferences". |
85 | # |
86 | # bounceback => nil or hash of bounceback data |
87 | # |
88 | # Enforced visit of a particular URL is in progress unless nil. For more |
89 | # information see "appctrl_enable_bounceback". |
90 | # |
91 | # masspay => nil or hash of mass payment data |
92 | # |
93 | # A mass payment session is in progress unless nil. For more information |
94 | # see the Payment Bulk Onsite Controller. |
95 | # |
96 | def get_preference( key_str ) |
97 | keys = key_str.split( '.' ) |
98 | pref = self.preferences |
99 | |
100 | for key in keys |
101 | return nil if pref.nil? |
102 | pref = pref[ key ] |
103 | end |
104 | |
105 | return pref |
106 | end |
107 | |
108 | # Set the value of a preference identified as for "get_preference" above. |
109 | # If any of the nested hashes identified by the key string are missing (e.g. |
110 | # in example "foo.bar.baz", any of hashes "foo", "bar" or "baz") then |
111 | # relevant entries in the preferences will be made automatically. |
112 | # |
113 | # The method saves 'self' back to database and returns the return value of |
114 | # the call made to "save". Thus returns 'false' on failure, else 'true'. |
115 | # |
116 | # See also "set_preference!". |
117 | # |
118 | def set_preference( key_str, value ) |
119 | return set_preference_by_method!( key_str, value, :save ) |
120 | end |
121 | |
122 | # As "set_preference" but returns the result of a call to "save!", so raises |
123 | # an exception on failure. |
124 | # |
125 | def set_preference!( key_str, value ) |
126 | return set_preference_by_method!( key_str, value, :save! ) |
127 | end |
128 | |
129 | # =========================================================================== |
130 | # PRIVATE |
131 | # =========================================================================== |
132 | |
133 | private |
134 | |
135 | # Implement "set_preference" and "set_preference!" - pass the preference |
136 | # key string, preference value and ":send" or ":send!" depending on the |
137 | # method required for saving the preference changes. |
138 | # |
139 | def set_preference_by_method!( key_str, value, method ) |
140 | keys = key_str.split( '.' ) |
141 | root = self.preferences || {} |
142 | pref = root |
143 | |
144 | keys.each_index do | index | |
145 | key = keys[ index ] |
146 | |
147 | if ( index == keys.size - 1 ) |
148 | pref[ key ] = value |
149 | else |
150 | pref[ key ] ||= {} |
151 | pref = pref[ key ] |
152 | end |
153 | end |
154 | |
155 | self.preferences = root |
156 | return self.send( method ) |
157 | end |
158 | end |