enju_question 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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>