enju_question 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +36 -0
  4. data/app/controllers/answers_controller.rb +140 -0
  5. data/app/controllers/questions_controller.rb +171 -0
  6. data/app/models/answer.rb +59 -0
  7. data/app/models/answer_has_item.rb +20 -0
  8. data/app/models/question.rb +87 -0
  9. data/app/models/question_sweeper.rb +17 -0
  10. data/app/views/answers/_form.html.erb +33 -0
  11. data/app/views/answers/edit.html.erb +13 -0
  12. data/app/views/answers/index.atom.builder +16 -0
  13. data/app/views/answers/index.html.erb +44 -0
  14. data/app/views/answers/index.rss.builder +31 -0
  15. data/app/views/answers/new.html.erb +14 -0
  16. data/app/views/answers/new.mobile.erb +35 -0
  17. data/app/views/answers/show.html.erb +54 -0
  18. data/app/views/questions/_crd.html.erb +24 -0
  19. data/app/views/questions/_index.html.erb +22 -0
  20. data/app/views/questions/_index_user.html.erb +18 -0
  21. data/app/views/questions/_list.html.erb +69 -0
  22. data/app/views/questions/_solved_facet.html.erb +21 -0
  23. data/app/views/questions/edit.html.erb +44 -0
  24. data/app/views/questions/index.atom.builder +16 -0
  25. data/app/views/questions/index.html.erb +5 -0
  26. data/app/views/questions/index.js.erb +2 -0
  27. data/app/views/questions/index.mobile.erb +21 -0
  28. data/app/views/questions/index.rss.builder +41 -0
  29. data/app/views/questions/index_crd.xml.builder +36 -0
  30. data/app/views/questions/new.html.erb +35 -0
  31. data/app/views/questions/show.html.erb +62 -0
  32. data/app/views/questions/show.mobile.erb +46 -0
  33. data/app/views/questions/show_crd.xml.builder +34 -0
  34. data/config/routes.rb +10 -0
  35. data/db/migrate/098_create_questions.rb +21 -0
  36. data/db/migrate/099_create_answers.rb +21 -0
  37. data/db/migrate/20100217054028_create_answer_has_items.rb +17 -0
  38. data/lib/enju_question/engine.rb +4 -0
  39. data/lib/enju_question/version.rb +3 -0
  40. data/lib/enju_question.rb +4 -0
  41. data/lib/tasks/enju_question_tasks.rake +4 -0
  42. data/spec/cassette_library/enju_ndl/crd.yml +440 -0
  43. data/spec/controllers/answers_controller_spec.rb +486 -0
  44. data/spec/controllers/questions_controller_spec.rb +559 -0
  45. data/spec/dummy/Rakefile +7 -0
  46. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  47. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  48. data/spec/dummy/app/controllers/application_controller.rb +106 -0
  49. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  50. data/spec/dummy/app/models/ability.rb +42 -0
  51. data/spec/dummy/app/models/item.rb +5 -0
  52. data/spec/dummy/app/models/role.rb +8 -0
  53. data/spec/dummy/app/models/user.rb +29 -0
  54. data/spec/dummy/app/models/user_group.rb +2 -0
  55. data/spec/dummy/app/models/user_has_role.rb +4 -0
  56. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  57. data/spec/dummy/app/views/page/403.html.erb +9 -0
  58. data/spec/dummy/app/views/page/403.mobile.erb +5 -0
  59. data/spec/dummy/app/views/page/403.xml.erb +4 -0
  60. data/spec/dummy/app/views/page/404.html.erb +9 -0
  61. data/spec/dummy/app/views/page/404.mobile.erb +5 -0
  62. data/spec/dummy/app/views/page/404.xml.erb +4 -0
  63. data/spec/dummy/config/application.rb +46 -0
  64. data/spec/dummy/config/boot.rb +10 -0
  65. data/spec/dummy/config/database.yml +25 -0
  66. data/spec/dummy/config/environment.rb +5 -0
  67. data/spec/dummy/config/environments/development.rb +30 -0
  68. data/spec/dummy/config/environments/production.rb +60 -0
  69. data/spec/dummy/config/environments/test.rb +39 -0
  70. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  71. data/spec/dummy/config/initializers/devise.rb +209 -0
  72. data/spec/dummy/config/initializers/inflections.rb +10 -0
  73. data/spec/dummy/config/initializers/mime_types.rb +6 -0
  74. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  75. data/spec/dummy/config/initializers/session_store.rb +8 -0
  76. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  77. data/spec/dummy/config/locales/en.yml +5 -0
  78. data/spec/dummy/config/routes.rb +60 -0
  79. data/spec/dummy/config.ru +4 -0
  80. data/spec/dummy/db/development.sqlite3 +0 -0
  81. data/spec/dummy/db/migrate/006_create_items.rb +36 -0
  82. data/spec/dummy/db/migrate/20100525171356_acts_as_taggable_on_migration.rb +30 -0
  83. data/spec/dummy/db/migrate/20111201121636_create_languages.rb +16 -0
  84. data/spec/dummy/db/migrate/20111201121844_create_roles.rb +12 -0
  85. data/spec/dummy/db/migrate/20111201155456_create_users.rb +13 -0
  86. data/spec/dummy/db/migrate/20111201155513_add_devise_to_users.rb +31 -0
  87. data/spec/dummy/db/migrate/20111201163342_create_user_groups.rb +12 -0
  88. data/spec/dummy/db/migrate/20111201163718_create_user_has_roles.rb +10 -0
  89. data/spec/dummy/db/schema.rb +168 -0
  90. data/spec/dummy/db/test.sqlite3 +0 -0
  91. data/spec/dummy/lib/expire_editable_fragment.rb +62 -0
  92. data/spec/dummy/log/development.log +2 -0
  93. data/spec/dummy/log/sunspot-solr-test.log +222 -0
  94. data/spec/dummy/log/test.log +77918 -0
  95. data/spec/dummy/public/404.html +26 -0
  96. data/spec/dummy/public/422.html +26 -0
  97. data/spec/dummy/public/500.html +26 -0
  98. data/spec/dummy/public/favicon.ico +0 -0
  99. data/spec/dummy/script/rails +6 -0
  100. data/spec/dummy/solr/conf/admin-extra.html +31 -0
  101. data/spec/dummy/solr/conf/elevate.xml +36 -0
  102. data/spec/dummy/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
  103. data/spec/dummy/solr/conf/protwords.txt +21 -0
  104. data/spec/dummy/solr/conf/schema.xml +238 -0
  105. data/spec/dummy/solr/conf/scripts.conf +24 -0
  106. data/spec/dummy/solr/conf/solrconfig.xml +934 -0
  107. data/spec/dummy/solr/conf/spellings.txt +2 -0
  108. data/spec/dummy/solr/conf/stopwords.txt +58 -0
  109. data/spec/dummy/solr/conf/synonyms.txt +31 -0
  110. data/spec/dummy/solr/data/test/index/segments.gen +0 -0
  111. data/spec/dummy/solr/data/test/index/segments_1 +0 -0
  112. data/spec/dummy/solr/data/test/spellchecker/segments.gen +0 -0
  113. data/spec/dummy/solr/data/test/spellchecker/segments_1 +0 -0
  114. data/spec/factories/answer.rb +7 -0
  115. data/spec/factories/question.rb +6 -0
  116. data/spec/factories/user.rb +34 -0
  117. data/spec/fixtures/answer_has_items.yml +26 -0
  118. data/spec/fixtures/answers.yml +61 -0
  119. data/spec/fixtures/questions.yml +61 -0
  120. data/spec/fixtures/roles.yml +21 -0
  121. data/spec/fixtures/user_groups.yml +25 -0
  122. data/spec/fixtures/user_has_roles.yml +41 -0
  123. data/spec/fixtures/users.yml +69 -0
  124. data/spec/models/answer_has_item_spec.rb +20 -0
  125. data/spec/models/answer_spec.rb +25 -0
  126. data/spec/spec_helper.rb +48 -0
  127. data/spec/support/controller_macros.rb +48 -0
  128. data/spec/support/devise.rb +4 -0
  129. data/spec/support/vcr.rb +6 -0
  130. metadata +306 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = EnjuQuestion
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'EnjuSubject'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ require 'rspec/core'
30
+ require 'rspec/core/rake_task'
31
+
32
+ RSpec::Core::RakeTask.new(:spec) do |spec|
33
+ spec.pattern = FileList['spec/**/*_spec.rb']
34
+ end
35
+
36
+ task :default => :spec
@@ -0,0 +1,140 @@
1
+ # -*- encoding: utf-8 -*-
2
+ class AnswersController < ApplicationController
3
+ load_and_authorize_resource :except => :index
4
+ authorize_resource :only => :index
5
+ before_filter :store_location, :only => [:index, :show, :new, :edit]
6
+ before_filter :get_user_if_nil, :except => [:edit]
7
+ before_filter :get_question
8
+ cache_sweeper :question_sweeper, :only => [:create, :update, :destroy]
9
+
10
+ # GET /answers
11
+ # GET /answers.json
12
+ def index
13
+ if !current_user.try(:has_role?, 'Librarian')
14
+ if @question
15
+ unless @question.try(:shared?)
16
+ access_denied; return
17
+ end
18
+ end
19
+ if @user != current_user
20
+ access_denied; return
21
+ end
22
+ end
23
+
24
+ @count = {}
25
+ if user_signed_in?
26
+ if current_user.has_role?('Librarian')
27
+ if @question
28
+ @answers = @question.answers.order('answers.id DESC').page(params[:page])
29
+ elsif @user
30
+ @answers = @user.answers.order('answers.id DESC').page(params[:page])
31
+ else
32
+ @answers = Answer.order('answers.id DESC').page(params[:page])
33
+ end
34
+ else
35
+ if @question
36
+ if @question.shared?
37
+ @answers = @question.answers.order('answers.id DESC').page(params[:page])
38
+ else
39
+ access_denied; return
40
+ end
41
+ elsif @user
42
+ if @user == current_user
43
+ @answers = @user.answers.order('answers.id DESC').page(params[:page])
44
+ else
45
+ access_denied; return
46
+ end
47
+ else
48
+ access_denied; return
49
+ end
50
+ end
51
+ else
52
+ if @question
53
+ @answers = @question.answers.order('answers.id DESC').page(params[:page])
54
+ else
55
+ access_denied; return
56
+ end
57
+ end
58
+ @count[:query_result] = @answers.size
59
+
60
+ respond_to do |format|
61
+ format.html # index.rhtml
62
+ format.json { render :json => @answers.to_json }
63
+ format.rss { render :layout => false }
64
+ format.atom
65
+ end
66
+ end
67
+
68
+ # GET /answers/1
69
+ # GET /answers/1.json
70
+ def show
71
+ respond_to do |format|
72
+ format.html # show.rhtml
73
+ format.json { render :json => @answer.to_json }
74
+ end
75
+ end
76
+
77
+ # GET /answers/new
78
+ def new
79
+ if @question
80
+ @answer = current_user.answers.new
81
+ @answer.question = @question
82
+ else
83
+ flash[:notice] = t('answer.specify_question')
84
+ redirect_to questions_url
85
+ end
86
+ end
87
+
88
+ # GET /answers/1;edit
89
+ def edit
90
+ end
91
+
92
+ # POST /answers
93
+ # POST /answers.json
94
+ def create
95
+ @answer = current_user.answers.new(params[:answer])
96
+ unless @answer.question
97
+ redirect_to questions_url
98
+ return
99
+ end
100
+
101
+ respond_to do |format|
102
+ if @answer.save
103
+ flash[:notice] = t('controller.successfully_created', :model => t('activerecord.models.answer'))
104
+ format.html { redirect_to(@answer) }
105
+ format.json { render :json => @answer, :status => :created, :location => answer_url(@answer) }
106
+ format.mobile { redirect_to question_url(@answer.question) }
107
+ else
108
+ format.html { render :action => "new" }
109
+ format.json { render :json => @answer.errors.to_json }
110
+ format.mobile { render :action => "new" }
111
+ end
112
+ end
113
+ end
114
+
115
+ # PUT /answers/1
116
+ # PUT /answers/1.json
117
+ def update
118
+ respond_to do |format|
119
+ if @answer.update_attributes(params[:answer])
120
+ flash[:notice] = t('controller.successfully_updated', :model => t('activerecord.models.answer'))
121
+ format.html { redirect_to(@answer) }
122
+ format.json { head :ok }
123
+ else
124
+ format.html { render :action => "edit" }
125
+ format.json { render :json => @answer.errors.to_json }
126
+ end
127
+ end
128
+ end
129
+
130
+ # DELETE /answers/1
131
+ # DELETE /answers/1.json
132
+ def destroy
133
+ @answer.destroy
134
+
135
+ respond_to do |format|
136
+ format.html { redirect_to question_answers_url(@answer.question) }
137
+ format.json { head :ok }
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,171 @@
1
+ # -*- encoding: utf-8 -*-
2
+ class QuestionsController < ApplicationController
3
+ before_filter :store_location, :only => [:index, :show, :new, :edit]
4
+ load_and_authorize_resource
5
+ before_filter :get_user_if_nil, :except => [:edit]
6
+ after_filter :solr_commit, :only => [:create, :update, :destroy]
7
+
8
+ # GET /questions
9
+ # GET /questions.json
10
+ def index
11
+ store_location
12
+ if @user and user_signed_in?
13
+ user = @user
14
+ end
15
+ c_user = current_user
16
+
17
+ session[:params] = {} unless session[:params]
18
+ session[:params][:question] = params
19
+
20
+ @count = {}
21
+ case params[:sort_by]
22
+ when 'updated_at'
23
+ sort_by = 'updated_at'
24
+ when 'created_at'
25
+ sort_by = 'created_at'
26
+ when 'answers_count'
27
+ sort_by = 'answers_count'
28
+ else
29
+ sort_by = 'updated_at'
30
+ end
31
+
32
+ case params[:solved]
33
+ when 'true'
34
+ solved = true
35
+ @solved = solved.to_s
36
+ when 'false'
37
+ solved = false
38
+ @solved = solved.to_s
39
+ end
40
+
41
+ search = Sunspot.new_search(Question)
42
+ query = params[:query].to_s.strip
43
+ unless query.blank?
44
+ @query = query.dup
45
+ query = query.gsub(' ', ' ')
46
+ search.build do
47
+ fulltext query
48
+ end
49
+ end
50
+ search.build do
51
+ order_by sort_by, :desc
52
+ end
53
+
54
+ search.build do
55
+ with(:username).equal_to user.username if user
56
+ if c_user != user
57
+ unless c_user.has_role?('Librarian')
58
+ with(:shared).equal_to true
59
+ end
60
+ end
61
+ facet :solved
62
+ end
63
+
64
+ @question_facet = search.execute!.facet(:solved).rows
65
+
66
+ if @solved
67
+ search.build do
68
+ with(:solved).equal_to solved
69
+ end
70
+ end
71
+
72
+ page = params[:page] || 1
73
+ search.query.paginate(page.to_i, Question.per_page)
74
+ result = search.execute!
75
+ @questions = result.results
76
+ @count[:query_result] = @questions.total_entries
77
+
78
+ if query.present?
79
+ begin
80
+ @crd_results = Question.search_crd(:query_01 => query, :page => params[:crd_page])
81
+ rescue Timeout::Error
82
+ @crd_results = WillPaginate::Collection.create(1,1,0) do end
83
+ end
84
+ end
85
+
86
+ respond_to do |format|
87
+ format.html # index.rhtml
88
+ format.json { render :json => @questions.to_json }
89
+ format.xml {
90
+ if params[:mode] == 'crd'
91
+ render :template => 'questions/index_crd'
92
+ convert_charset
93
+ else
94
+ render :xml => @questions.to_xml
95
+ end
96
+ }
97
+ format.rss { render :layout => false }
98
+ format.atom
99
+ format.js
100
+ end
101
+ end
102
+
103
+ # GET /questions/1
104
+ # GET /questions/1.json
105
+ def show
106
+ respond_to do |format|
107
+ format.html # show.rhtml
108
+ format.json { render :json => @answer.to_json }
109
+ format.xml {
110
+ if params[:mode] == 'crd'
111
+ render :template => 'questions/show_crd'
112
+ convert_charset
113
+ else
114
+ render :json => @question.to_xml
115
+ end
116
+ }
117
+ end
118
+ end
119
+
120
+ # GET /questions/new
121
+ def new
122
+ @question = current_user.questions.new
123
+ end
124
+
125
+ # GET /questions/1;edit
126
+ def edit
127
+ end
128
+
129
+ # POST /questions
130
+ # POST /questions.json
131
+ def create
132
+ @question = current_user.questions.new(params[:question])
133
+
134
+ respond_to do |format|
135
+ if @question.save
136
+ flash[:notice] = t('controller.successfully_created', :model => t('activerecord.models.question'))
137
+ format.html { redirect_to @question }
138
+ format.json { render :json => @question, :status => :created, :location => question_url(@question) }
139
+ else
140
+ format.html { render :action => "new" }
141
+ format.json { render :json => @question.errors.to_json }
142
+ end
143
+ end
144
+ end
145
+
146
+ # PUT /questions/1
147
+ # PUT /questions/1.json
148
+ def update
149
+ respond_to do |format|
150
+ if @question.update_attributes(params[:question])
151
+ flash[:notice] = t('controller.successfully_updated', :model => t('activerecord.models.question'))
152
+ format.html { redirect_to @question }
153
+ format.json { head :ok }
154
+ else
155
+ format.html { render :action => "edit" }
156
+ format.json { render :json => @question.errors.to_json }
157
+ end
158
+ end
159
+ end
160
+
161
+ # DELETE /questions/1
162
+ # DELETE /questions/1.json
163
+ def destroy
164
+ @question.destroy
165
+
166
+ respond_to do |format|
167
+ format.html { redirect_to user_questions_url(@question.user) }
168
+ format.json { head :ok }
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,59 @@
1
+ # -*- encoding: utf-8 -*-
2
+ class Answer < ActiveRecord::Base
3
+ default_scope :order => 'id ASC'
4
+ #scope :public_answers, where(:shared => true)
5
+ #scope :private_answers, where(:shared => false)
6
+ belongs_to :user, :validate => true
7
+ belongs_to :question, :validate => true
8
+ has_many :answer_has_items, :dependent => :destroy
9
+ has_many :items, :through => :answer_has_items
10
+
11
+ after_save :save_questions
12
+ before_save :add_items
13
+
14
+ validates_associated :user, :question
15
+ validates_presence_of :user, :question, :body
16
+ validate :check_url_list
17
+
18
+ def self.per_page
19
+ 10
20
+ end
21
+
22
+ def save_questions
23
+ self.question.save
24
+ end
25
+
26
+ def add_items
27
+ item_list = item_identifier_list.to_s.strip.split.map{|i| Item.where(:item_identifier => i).first}.compact.uniq
28
+ url_list = add_urls
29
+ self.items = item_list + url_list
30
+ end
31
+
32
+ def add_urls
33
+ list = url_list.to_s.strip.split.map{|u| Manifestation.where(:access_address => Addressable::URI.parse(u).normalize.to_s).first}.compact.map{|m| m.web_item}.compact.uniq
34
+ end
35
+
36
+ def check_url_list
37
+ url_list.to_s.strip.split.each do |url|
38
+ errors.add(:url_list) unless Addresable::URI.parse(url).host
39
+ end
40
+ end
41
+ end
42
+
43
+
44
+ # == Schema Information
45
+ #
46
+ # Table name: answers
47
+ #
48
+ # id :integer not null, primary key
49
+ # user_id :integer not null
50
+ # question_id :integer not null
51
+ # body :text
52
+ # created_at :datetime
53
+ # updated_at :datetime
54
+ # deleted_at :datetime
55
+ # state :string(255)
56
+ # item_identifier_list :text
57
+ # url_list :text
58
+ #
59
+
@@ -0,0 +1,20 @@
1
+ class AnswerHasItem < ActiveRecord::Base
2
+ belongs_to :answer
3
+ belongs_to :item
4
+
5
+ validates_uniqueness_of :item_id, :scope => :answer_id
6
+ acts_as_list :scope => :answer_id
7
+ end
8
+
9
+ # == Schema Information
10
+ #
11
+ # Table name: answer_has_items
12
+ #
13
+ # id :integer not null, primary key
14
+ # answer_id :integer
15
+ # item_id :integer
16
+ # position :integer
17
+ # created_at :datetime
18
+ # updated_at :datetime
19
+ #
20
+
@@ -0,0 +1,87 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'timeout'
3
+ class Question < ActiveRecord::Base
4
+ default_scope :order => 'id DESC'
5
+ scope :public_questions, where(:shared => true)
6
+ scope :private_questions, where(:shared => false)
7
+ scope :solved, where(:solved => true)
8
+ scope :unsolved, where(:solved => false)
9
+ belongs_to :user, :validate => true
10
+ has_many :answers, :dependent => :destroy
11
+
12
+ validates_associated :user
13
+ validates_presence_of :user, :body
14
+
15
+ searchable do
16
+ text :body, :answer_body
17
+ string :username
18
+ time :created_at
19
+ time :updated_at do
20
+ last_updated_at
21
+ end
22
+ boolean :shared
23
+ boolean :solved
24
+ integer :answers_count
25
+ integer :manifestation_id, :multiple => true do
26
+ answers.collect(&:items).flatten.collect{|i| i.manifestation.id}
27
+ end
28
+ end
29
+
30
+ acts_as_taggable_on :tags
31
+ enju_ndl_crd
32
+
33
+ def self.per_page
34
+ 10
35
+ end
36
+
37
+ def self.crd_per_page
38
+ 5
39
+ end
40
+
41
+ def answer_body
42
+ text = ""
43
+ self.reload
44
+ self.answers.each do |answer|
45
+ text += answer.body
46
+ end
47
+ return text
48
+ end
49
+
50
+ def username
51
+ self.user.try(:username)
52
+ end
53
+
54
+ def last_updated_at
55
+ if answers.last
56
+ time = answers.last.updated_at
57
+ end
58
+ if time
59
+ if time > updated_at
60
+ time
61
+ else
62
+ updated_at
63
+ end
64
+ else
65
+ updated_at
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ # == Schema Information
72
+ #
73
+ # Table name: questions
74
+ #
75
+ # id :integer not null, primary key
76
+ # user_id :integer not null
77
+ # body :text
78
+ # shared :boolean default(TRUE), not null
79
+ # answers_count :integer default(0), not null
80
+ # created_at :datetime
81
+ # updated_at :datetime
82
+ # deleted_at :datetime
83
+ # state :string(255)
84
+ # solved :boolean default(FALSE), not null
85
+ # note :text
86
+ #
87
+
@@ -0,0 +1,17 @@
1
+ class QuestionSweeper < ActionController::Caching::Sweeper
2
+ observe Answer
3
+ include ExpireEditableFragment
4
+
5
+ def after_save(record)
6
+ case record.to_s.to_sym
7
+ when :Answer
8
+ record.items.each do |item|
9
+ expire_editable_fragment(item.manifestation, ['detail'])
10
+ end
11
+ end
12
+ end
13
+
14
+ def after_destroy(record)
15
+ after_save(record)
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ <%= simple_form_for(@answer, :validate => true) do |f| %>
2
+ <%= f.error_notification %>
3
+ <%= f.hidden_field :question_id %>
4
+
5
+ <div class="field">
6
+ <%= f.label t('activerecord.models.user') %><br />
7
+ <%= link_to @answer.user.username, @answer.user %>
8
+ </div>
9
+
10
+ <div class="field">
11
+ <%= f.label t('activerecord.models.question') %><br />
12
+ <%= link_to @answer.question.body, @answer.question %>
13
+ </div>
14
+
15
+ <div class="field">
16
+ <%= f.label :body %><br />
17
+ <%= f.text_area :body, :class => 'resource_textarea' %>
18
+ </div>
19
+
20
+ <div class="field">
21
+ <%= f.label :item_identifier_list %><br />
22
+ <%= f.text_area :item_identifier_list, :class => 'resource_textarea' %>
23
+ </div>
24
+
25
+ <div class="field">
26
+ <%= f.label :url_list %><br />
27
+ <%= f.text_area :url_list, :class => 'resource_textarea' %>
28
+ </div>
29
+
30
+ <div class="actions">
31
+ <%= f.submit %>
32
+ </div>
33
+ <%- end %>
@@ -0,0 +1,13 @@
1
+ <div id="content_detail" class="ui-corner-all">
2
+ <h1 class="title"><%= t('page.editing', :model => t('activerecord.models.answer')) -%></h1>
3
+ <div id="content_list">
4
+ <%= render 'form' %>
5
+ </div>
6
+ </div>
7
+
8
+ <div id="submenu" class="ui-corner-all">
9
+ <ul>
10
+ <li><%= link_to t('page.show'), @answer -%></li>
11
+ <li><%= link_to t('page.back'), question_answers_path(@answer.question) -%></li>
12
+ </ul>
13
+ </div>
@@ -0,0 +1,16 @@
1
+ atom_feed(:url => answers_url(:format => :atom)) do |feed|
2
+ if @user
3
+ feed.title t('answer.user_answer', :login_name => @user.username)
4
+ else
5
+ feed.title t('answer.library_group_answer', :library_group_name => @library_group.display_name.localize)
6
+ end
7
+ feed.updated(@answers.first ? @answers.first.created_at : Time.zone.now)
8
+
9
+ @answers.each do |answer|
10
+ feed.entry(answer) do |entry|
11
+ entry.title(truncate(answer.body))
12
+ entry.author(answer.user.username)
13
+ entry.content(answer.body)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ <div id="content_detail" class="ui-corner-all">
2
+ <h1 class="title"><%= t('page.listing', :model => t('activerecord.models.answer')) -%></h1>
3
+ <div id="content_list">
4
+
5
+ <%- if @question -%>
6
+ <p><%= link_to textilize(h(@question.body)), @question -%></p>
7
+ <%- end -%>
8
+
9
+ <table class="index">
10
+ <tr>
11
+ <th><%= t('activerecord.models.user') -%></th>
12
+ <th><%= t('activerecord.attributes.answer.body') -%></th>
13
+ <th><%= t('page.created_at') -%></th>
14
+ <th><%= t('page.updated_at') -%></th>
15
+ <th></th>
16
+ </tr>
17
+
18
+ <%- @answers.each_with_index do |answer, i| -%>
19
+ <tr class="line<%= cycle("0", "1") -%>">
20
+ <td><%= link_to answer.user.username, answer.user -%></td>
21
+ <td><%= link_to truncate(answer.body, :length => 20), answer -%></td>
22
+ <td><%= l(answer.created_at) -%></td>
23
+ <td><%= l(answer.updated_at) -%></td>
24
+ <td>
25
+ <%- if can? :destroy, answer -%>
26
+ <%= link_to t('page.edit'), edit_answer_path(answer) -%>
27
+ <%= link_to t('page.destroy'), answer, :confirm => t('page.are_you_sure'), :method => :delete -%>
28
+ <%- end -%>
29
+ </td>
30
+ </tr>
31
+ <%- end -%>
32
+ </table>
33
+
34
+ <%= will_paginate(@answers) -%>
35
+ </div>
36
+ </div>
37
+
38
+ <div id="submenu" class="ui-corner-all">
39
+ <%- if @question -%>
40
+ <ul>
41
+ <li><%= link_to t('page.new', :model => t('activerecord.models.answer')), new_question_answer_path(@question) -%></li>
42
+ </ul>
43
+ <%- end -%>
44
+ </div>