Commit c5e6187faf2bd455ad3560fc9e29f154decd1661

Authored by Diego Camarinha
Committed by Paulo Meireles
1 parent 3d1e7d49

[Mezuro] Add native metric configuration.

plugins/mezuro/controllers/myprofile/mezuro_plugin_metric_configuration_controller.rb
@@ -7,11 +7,27 @@ class MezuroPluginMetricConfigurationController < MezuroPluginMyprofileControlle @@ -7,11 +7,27 @@ class MezuroPluginMetricConfigurationController < MezuroPluginMyprofileControlle
7 @base_tools = Kalibro::BaseTool.all 7 @base_tools = Kalibro::BaseTool.all
8 end 8 end
9 9
10 - def new_metric_configuration 10 + def new_native
11 @configuration_content = profile.articles.find(params[:id]) 11 @configuration_content = profile.articles.find(params[:id])
12 - @metric = Kalibro::BaseTool.find_by_name(params[:base_tool]).metric params[:metric_name] 12 + @base_tool_name = params[:base_tool_name]
  13 + @metric = Kalibro::BaseTool.find_by_name(@base_tool_name).metric params[:metric_name]
  14 + @reading_group_names_and_ids = reading_group_names_and_ids
13 end 15 end
14 - 16 +
  17 + def create_native
  18 + metric_configuration = Kalibro::MetricConfiguration.new(params[:metric_configuration])
  19 + metric_configuration.save
  20 +
  21 + if metric_configuration_has_errors? metric_configuration
  22 + redirect_to_error_page metric_configuration.errors[0].message
  23 + else
  24 + id = params[:id]
  25 + metric_name = params[:metric_configuration][:metric][:name]
  26 + redirect_to "/myprofile/#{profile.identifier}/plugin/mezuro/metric_configuration/edit_native?id=#{id}&metric_name=#{metric_name.gsub(/\s/, '+')}"
  27 + end
  28 + end
  29 +
  30 +=begin
15 def new_compound_metric_configuration 31 def new_compound_metric_configuration
16 @configuration_content = profile.articles.find(params[:id]) 32 @configuration_content = profile.articles.find(params[:id])
17 @metric_configurations = @configuration_content.metric_configurations 33 @metric_configurations = @configuration_content.metric_configurations
@@ -33,17 +49,6 @@ class MezuroPluginMetricConfigurationController < MezuroPluginMyprofileControlle @@ -33,17 +49,6 @@ class MezuroPluginMetricConfigurationController < MezuroPluginMyprofileControlle
33 @metric = @metric_configuration.metric 49 @metric = @metric_configuration.metric
34 end 50 end
35 51
36 - def create_metric_configuration  
37 - id = params[:id]  
38 - metric_name = params[:metric_configuration][:metric][:name]  
39 - metric_configuration = Kalibro::MetricConfiguration.new(params[:metric_configuration])  
40 - metric_configuration.save  
41 - if metric_configuration_has_errors? metric_configuration  
42 - redirect_to_error_page metric_configuration.errors[0].message  
43 - else  
44 - redirect_to "/myprofile/#{profile.identifier}/plugin/mezuro/metric_configuration/edit_metric_configuration?id=#{id}&metric_name=#{metric_name.gsub(/\s/, '+')}"  
45 - end  
46 - end  
47 52
48 def create_compound_metric_configuration 53 def create_compound_metric_configuration
49 id = params[:id] 54 id = params[:id]
@@ -92,11 +97,20 @@ class MezuroPluginMetricConfigurationController < MezuroPluginMyprofileControlle @@ -92,11 +97,20 @@ class MezuroPluginMetricConfigurationController < MezuroPluginMyprofileControlle
92 redirect_to "/#{profile.identifier}/#{configuration_content.slug}" 97 redirect_to "/#{profile.identifier}/#{configuration_content.slug}"
93 end 98 end
94 end 99 end
  100 +=end
95 101
96 private 102 private
97 103
  104 + def reading_group_names_and_ids
  105 + array = Kalibro::ReadingGroup.all.map { |reading_group| [reading_group.name, reading_group.id] }
  106 + array.sort { |x,y| x.first.downcase <=> y.first.downcase }
  107 + end
  108 +
  109 + def metric_configuration_has_errors? metric_configuration
  110 + not metric_configuration.errors.empty?
  111 + end
  112 +
98 def configuration_content_has_errors? 113 def configuration_content_has_errors?
99 not @configuration_content.errors[:base].nil? 114 not @configuration_content.errors[:base].nil?
100 end 115 end
101 -  
102 end 116 end
plugins/mezuro/controllers/myprofile/mezuro_plugin_myprofile_controller.rb
@@ -18,11 +18,7 @@ class MezuroPluginMyprofileController &lt; ProfileController #MyprofileController? @@ -18,11 +18,7 @@ class MezuroPluginMyprofileController &lt; ProfileController #MyprofileController?
18 redirect_to "/myprofile/#{profile.identifier}/plugin/mezuro/error_page?message=#{message}" 18 redirect_to "/myprofile/#{profile.identifier}/plugin/mezuro/error_page?message=#{message}"
19 end 19 end
20 20
21 - def metric_configuration_has_errors? metric_configuration  
22 - not metric_configuration.errors.empty?  
23 - end  
24 -  
25 - def process_error_message message 21 + def process_error_message message #FIXME
26 if message =~ /bla/ 22 if message =~ /bla/
27 message 23 message
28 else 24 else
plugins/mezuro/lib/kalibro/metric.rb
1 class Kalibro::Metric < Kalibro::Model 1 class Kalibro::Metric < Kalibro::Model
2 2
3 - attr_accessor :name, :compound, :scope, :description, :script, :origin, :language 3 + attr_accessor :name, :compound, :scope, :description, :script, :language
4 4
5 def languages 5 def languages
6 @language 6 @language
plugins/mezuro/lib/mezuro_plugin/helpers/content_viewer_helper.rb
@@ -52,6 +52,11 @@ class MezuroPlugin::Helpers::ContentViewerHelper @@ -52,6 +52,11 @@ class MezuroPlugin::Helpers::ContentViewerHelper
52 MezuroPluginModuleResultController.helpers.distance_of_time_in_words(0, seconds, include_seconds = true) 52 MezuroPluginModuleResultController.helpers.distance_of_time_in_words(0, seconds, include_seconds = true)
53 end 53 end
54 54
  55 + def self.aggregation_options
  56 + [["Average","AVERAGE"], ["Median", "MEDIAN"], ["Maximum", "MAXIMUM"], ["Minimum", "MINIMUM"],
  57 + ["Count", "COUNT"], ["Standard Deviation", "STANDARD_DEVIATION"]]
  58 + end
  59 +
55 private 60 private
56 61
57 def self.discretize_array(array) 62 def self.discretize_array(array)
plugins/mezuro/test/fixtures/metric_fixtures.rb
@@ -13,7 +13,7 @@ class MetricFixtures @@ -13,7 +13,7 @@ class MetricFixtures
13 end 13 end
14 14
15 def self.total_cof_hash 15 def self.total_cof_hash
16 - {:name => 'Total Coupling Factor', :compound => "false", :scope => 'APPLICATION', :origin => 'Analizo', :language => ['JAVA']} 16 + {:name => 'Total Coupling Factor', :compound => "false", :scope => 'APPLICATION', :language => ['JAVA']}
17 end 17 end
18 18
19 def self.amloc 19 def self.amloc
@@ -21,7 +21,7 @@ class MetricFixtures @@ -21,7 +21,7 @@ class MetricFixtures
21 end 21 end
22 22
23 def self.amloc_hash 23 def self.amloc_hash
24 - {:name => 'Average Method LOC', :compound => "false", :scope => 'CLASS', :origin => 'Analizo', :language => ['JAVA']} 24 + {:name => 'Average Method LOC', :compound => "false", :scope => 'CLASS', :language => ['JAVA']}
25 end 25 end
26 26
27 end 27 end
plugins/mezuro/test/functional/myprofile/mezuro_plugin_metric_configuration_controller_test.rb
@@ -4,6 +4,7 @@ require &quot;#{RAILS_ROOT}/plugins/mezuro/test/fixtures/base_tool_fixtures&quot; @@ -4,6 +4,7 @@ require &quot;#{RAILS_ROOT}/plugins/mezuro/test/fixtures/base_tool_fixtures&quot;
4 require "#{RAILS_ROOT}/plugins/mezuro/test/fixtures/metric_fixtures" 4 require "#{RAILS_ROOT}/plugins/mezuro/test/fixtures/metric_fixtures"
5 require "#{RAILS_ROOT}/plugins/mezuro/test/fixtures/metric_configuration_fixtures" 5 require "#{RAILS_ROOT}/plugins/mezuro/test/fixtures/metric_configuration_fixtures"
6 require "#{RAILS_ROOT}/plugins/mezuro/test/fixtures/configuration_fixtures" 6 require "#{RAILS_ROOT}/plugins/mezuro/test/fixtures/configuration_fixtures"
  7 +require "#{RAILS_ROOT}/plugins/mezuro/test/fixtures/reading_group_fixtures"
7 8
8 class MezuroPluginMetricConfigurationControllerTest < ActionController::TestCase 9 class MezuroPluginMetricConfigurationControllerTest < ActionController::TestCase
9 10
@@ -26,8 +27,11 @@ class MezuroPluginMetricConfigurationControllerTest &lt; ActionController::TestCase @@ -26,8 +27,11 @@ class MezuroPluginMetricConfigurationControllerTest &lt; ActionController::TestCase
26 @base_tool = BaseToolFixtures.base_tool 27 @base_tool = BaseToolFixtures.base_tool
27 @base_tool_hash = BaseToolFixtures.base_tool_hash 28 @base_tool_hash = BaseToolFixtures.base_tool_hash
28 29
29 -=begin  
30 @metric = MetricFixtures.amloc 30 @metric = MetricFixtures.amloc
  31 +
  32 + @reading_group = ReadingGroupFixtures.reading_group
  33 +
  34 +=begin
31 @metric_configuration = MetricConfigurationFixtures.amloc_metric_configuration 35 @metric_configuration = MetricConfigurationFixtures.amloc_metric_configuration
32 @metric_configuration_hash = MetricConfigurationFixtures.amloc_metric_configuration_hash 36 @metric_configuration_hash = MetricConfigurationFixtures.amloc_metric_configuration_hash
33 @compound_metric_configuration = MetricConfigurationFixtures.sc_metric_configuration 37 @compound_metric_configuration = MetricConfigurationFixtures.sc_metric_configuration
@@ -49,16 +53,25 @@ class MezuroPluginMetricConfigurationControllerTest &lt; ActionController::TestCase @@ -49,16 +53,25 @@ class MezuroPluginMetricConfigurationControllerTest &lt; ActionController::TestCase
49 assert_response 200 53 assert_response 200
50 end 54 end
51 55
52 -=begin  
53 - should 'test new metric configuration' do  
54 - Kalibro::BaseTool.expects(:request).with("BaseTool", :get_base_tool, {:base_tool_name => @base_tool.name}).returns({:base_tool => @base_tool_hash})  
55 - get :new_metric_configuration, :profile => @profile.identifier, :id => @content.id, :base_tool => @base_tool.name, :metric_name => @metric.name 56 + should 'test new native metric configuration' do
  57 + Kalibro::BaseTool.expects(:find_by_name).with(@base_tool.name).returns(@base_tool)
  58 + Kalibro::ReadingGroup.expects(:all).returns([@reading_group])
  59 + get :new_native, :profile => @profile.identifier, :id => @content.id, :base_tool_name => @base_tool.name, :metric_name => @metric.name
56 assert_equal @content, assigns(:configuration_content) 60 assert_equal @content, assigns(:configuration_content)
57 assert_equal @metric.name, assigns(:metric).name 61 assert_equal @metric.name, assigns(:metric).name
  62 + assert_equal @base_tool.name, assigns(:base_tool_name)
  63 + assert_equal [[@reading_group.name,@reading_group.id]], assigns(:reading_group_names_and_ids)
58 assert_response 200 64 assert_response 200
59 end 65 end
60 66
  67 + should 'test create native metric configuration' do
  68 + Kalibro::MetricConfiguration.expects(:new).with(@metric_configuration_hash).returns(@created_metric_configuration)
  69 + @created_metric_configuration.expects(:save).returns(true)
  70 + get :create_native, :profile => @profile.identifier, :id => @content.id, :metric_configuration => @native_hash
  71 + assert_response 200
  72 + end
61 73
  74 +=begin
62 should 'test new compound metric configuration' do 75 should 'test new compound metric configuration' do
63 Kalibro::Configuration.expects(:request).with("Configuration", :get_configuration, { 76 Kalibro::Configuration.expects(:request).with("Configuration", :get_configuration, {
64 :configuration_name => @content.name}).returns({:configuration => @configuration_hash}) 77 :configuration_name => @content.name}).returns({:configuration => @configuration_hash})
@@ -95,16 +108,6 @@ class MezuroPluginMetricConfigurationControllerTest &lt; ActionController::TestCase @@ -95,16 +108,6 @@ class MezuroPluginMetricConfigurationControllerTest &lt; ActionController::TestCase
95 assert_response 200 108 assert_response 200
96 end 109 end
97 110
98 - should 'test create native metric configuration' do  
99 - Kalibro::MetricConfiguration.expects(:request).with("MetricConfiguration", :save_metric_configuration, {  
100 - :metric_configuration => @metric_configuration.to_hash,  
101 - :configuration_name => @metric_configuration.configuration_name})  
102 - get :create_metric_configuration,  
103 - :profile => @profile.identifier,  
104 - :id => @content.id,  
105 - :metric_configuration => @native_hash  
106 - assert_response 302  
107 - end  
108 111
109 should 'test compound metric creation' do 112 should 'test compound metric creation' do
110 Kalibro::MetricConfiguration.expects(:request).with("MetricConfiguration", :save_metric_configuration, { 113 Kalibro::MetricConfiguration.expects(:request).with("MetricConfiguration", :save_metric_configuration, {
plugins/mezuro/test/unit/mezuro_plugin/helpers/content_viewer_helper_test.rb
@@ -55,4 +55,9 @@ class ContentViewerHelperTest &lt; ActiveSupport::TestCase @@ -55,4 +55,9 @@ class ContentViewerHelperTest &lt; ActiveSupport::TestCase
55 assert_equal 'AverageMethodLOC', @helper.format_name(metric_configuration_snapshot) 55 assert_equal 'AverageMethodLOC', @helper.format_name(metric_configuration_snapshot)
56 end 56 end
57 57
  58 + should 'create aggregation options array' do
  59 + assert_equal [["Average","AVERAGE"], ["Median", "MEDIAN"], ["Maximum", "MAXIMUM"], ["Minimum", "MINIMUM"],
  60 + ["Count", "COUNT"], ["Standard Deviation", "STANDARD_DEVIATION"]], @helper.aggregation_options
  61 + end
  62 +
58 end 63 end
plugins/mezuro/views/content_viewer/show_configuration.rhtml
@@ -53,7 +53,7 @@ @@ -53,7 +53,7 @@
53 </td> 53 </td>
54 <% else %> 54 <% else %>
55 <td> 55 <td>
56 - <%= metric_configuration.metric.origin %> 56 + <%= metric_configuration.base_tool_name %>
57 </td> 57 </td>
58 <% end %> 58 <% end %>
59 <td><%= metric_configuration.code %></td> 59 <td><%= metric_configuration.code %></td>
plugins/mezuro/views/mezuro_plugin_metric_configuration/choose_metric.html.erb
@@ -10,8 +10,8 @@ @@ -10,8 +10,8 @@
10 10
11 <div id="<%=base_tool.name%>" style="display:none"> 11 <div id="<%=base_tool.name%>" style="display:none">
12 <% base_tool.supported_metrics.each do |metric| %> 12 <% base_tool.supported_metrics.each do |metric| %>
13 - &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<%= link_to metric.name, :controller => "mezuro_plugin_metric_configuration", :action => "new_metric_configuration",  
14 - :metric_name => metric.name, :base_tool => base_tool.name, :id => @configuration_content.id %> 13 + &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<%= link_to metric.name, :controller => "mezuro_plugin_metric_configuration", :action => "new_native",
  14 + :metric_name => metric.name, :base_tool_name => base_tool.name, :id => @configuration_content.id %>
15 <hr size="1" width="93%"/> 15 <hr size="1" width="93%"/>
16 <% end %> 16 <% end %>
17 </div> 17 </div>
plugins/mezuro/views/mezuro_plugin_metric_configuration/edit.html.erb 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +<script src="/plugins/mezuro/javascripts/validations.js" type="text/javascript"></script>
  2 +<script src="/javascripts/colorpicker.js" type="text/javascript"></script>
  3 +<script src="/javascripts/colorpicker-noosfero.js" type="text/javascript"></script>
  4 +
  5 +<h2><%= @configuration_content.name %> Configuration</h2>
  6 +
  7 +<% owner = (not user.nil?) && user.id == @profile.id %>
  8 +
  9 +<% if owner %>
  10 + <%= render :partial => "content_viewer/metric_configuration_form" %>
  11 +<% else %>
  12 + <%= render :partial => "content_viewer/metric_configuration_view" %>
  13 +<% end %>
  14 +
  15 +<h5> Ranges </h5><br/>
  16 +
  17 +<table id="ranges">
  18 + <tr>
  19 + <td>
  20 + Label
  21 + </td>
  22 + <td>
  23 + Beginning
  24 + </td>
  25 + <td>
  26 + End
  27 + </td>
  28 + <td>
  29 + Grade
  30 + </td>
  31 + <td>
  32 + Color
  33 + </td>
  34 + <td></td>
  35 + <td></td>
  36 + </tr>
  37 + <% if (@metric_configuration.ranges!=nil)
  38 + @metric_configuration.ranges.each do |range| %>
  39 + <%= render :partial => "mezuro_plugin_range/range", :locals => {:range => range, :id => @configuration_content.id,
  40 + :metric_name => @metric.name} %>
  41 + <% end
  42 + end %>
  43 +</table>
  44 +
  45 +<br/>
  46 +<% if owner %>
  47 + <%= link_to_remote "New Range", :url => {:action =>"new_range", :controller => "mezuro_plugin_range", :id => @configuration_content.id, :metric_name => @metric.name} %>
  48 +<% end %>
  49 +<div id="range_form" style="display:none"></div>
  50 +
plugins/mezuro/views/mezuro_plugin_metric_configuration/edit_metric_configuration.html.erb
@@ -1,50 +0,0 @@ @@ -1,50 +0,0 @@
1 -<script src="/plugins/mezuro/javascripts/validations.js" type="text/javascript"></script>  
2 -<script src="/javascripts/colorpicker.js" type="text/javascript"></script>  
3 -<script src="/javascripts/colorpicker-noosfero.js" type="text/javascript"></script>  
4 -  
5 -<h2><%= @configuration_content.name %> Configuration</h2>  
6 -  
7 -<% owner = (not user.nil?) && user.id == @profile.id %>  
8 -  
9 -<% if owner %>  
10 - <%= render :partial => "content_viewer/metric_configuration_form" %>  
11 -<% else %>  
12 - <%= render :partial => "content_viewer/metric_configuration_view" %>  
13 -<% end %>  
14 -  
15 -<h5> Ranges </h5><br/>  
16 -  
17 -<table id="ranges">  
18 - <tr>  
19 - <td>  
20 - Label  
21 - </td>  
22 - <td>  
23 - Beginning  
24 - </td>  
25 - <td>  
26 - End  
27 - </td>  
28 - <td>  
29 - Grade  
30 - </td>  
31 - <td>  
32 - Color  
33 - </td>  
34 - <td></td>  
35 - <td></td>  
36 - </tr>  
37 - <% if (@metric_configuration.ranges!=nil)  
38 - @metric_configuration.ranges.each do |range| %>  
39 - <%= render :partial => "mezuro_plugin_range/range", :locals => {:range => range, :id => @configuration_content.id,  
40 - :metric_name => @metric.name} %>  
41 - <% end  
42 - end %>  
43 -</table>  
44 -  
45 -<br/>  
46 -<% if owner %>  
47 - <%= link_to_remote "New Range", :url => {:action =>"new_range", :controller => "mezuro_plugin_range", :id => @configuration_content.id, :metric_name => @metric.name} %>  
48 -<% end %>  
49 -<div id="range_form" style="display:none"></div>  
50 -  
plugins/mezuro/views/mezuro_plugin_metric_configuration/new_metric_configuration.html.erb
@@ -1,51 +0,0 @@ @@ -1,51 +0,0 @@
1 -<script src="/plugins/mezuro/javascripts/validations.js" type="text/javascript"></script>  
2 -  
3 -<h2><%= @configuration_content.name %> Configuration</h2>  
4 -  
5 -<% form_for :metric_configuration, :url => {:action =>"create_metric_configuration", :controller => "mezuro_plugin_metric_configuration"}, :method => :get do |f| %>  
6 - <%= hidden_field_tag :id, @configuration_content.id %>  
7 - <%= f.hidden_field :configuration_name, :value => @configuration_content.name %>  
8 -  
9 - <% f.fields_for :metric do |m| %>  
10 -  
11 - <% @metric.language.each do |language| %>  
12 - <%= m.hidden_field :language, :multiple => true, :value => language %>  
13 - <% end %>  
14 -  
15 - <%= m.hidden_field "scope", :value => @metric.scope %>  
16 - <p>  
17 - <%= m.label :origin, "Collector Name:" %>  
18 - <%= @metric.origin %>  
19 - <%= m.hidden_field "origin", :value => @metric.origin %>  
20 - </p>  
21 - <p>  
22 - <%= m.label :name, "Metric Name:" %>  
23 - <%= @metric.name %>  
24 - <%= m.hidden_field "name", :value => @metric.name %>  
25 - </p>  
26 - <!--<p>-->  
27 - <% m.label :description, "Description:" %>  
28 - <% @metric.description %>  
29 - <% m.hidden_field "description", :value => @metric.description %>  
30 - <!--</p>-->  
31 - <% end %>  
32 - <p>  
33 - <%= f.label :code, "Code:" %>  
34 - <%= f.text_field :code %>  
35 - </p>  
36 - <p>  
37 - <%= f.label :aggregation_form, "Aggregation Form:" %>  
38 - <%= f.select :aggregation_form, [["Average","AVERAGE"], ["Median", "MEDIAN"], ["Maximum", "MAXIMUM"], ["Minimum", "MINIMUM"],  
39 - ["Count", "COUNT"], ["Standard Deviation", "STANDARD_DEVIATION"]] %>  
40 - </p>  
41 - <p>  
42 - <%= f.label :weight, "Weight:" %>  
43 - <%= f.text_field :weight %>  
44 - </p>  
45 -  
46 - <p>  
47 - <%= f.submit "Add" %>  
48 - </p>  
49 -  
50 -<% end %>  
51 -  
plugins/mezuro/views/mezuro_plugin_metric_configuration/new_native.html.erb 0 → 100644
@@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
  1 +<script src="/plugins/mezuro/javascripts/validations.js" type="text/javascript"></script>
  2 +
  3 +<h2><%= @configuration_content.name %> Configuration</h2>
  4 +
  5 +<%= hidden_field_tag :id, @configuration_content.id %>
  6 +<% form_for :metric_configuration, :url => {:action =>"create_native", :controller => "mezuro_plugin_metric_configuration"}, :method => :get do |f| %>
  7 + <%= f.hidden_field :configuration_id, :value => @configuration_content.configuration_id %>
  8 +
  9 + <%= labelled_form_field _('Collector Name:'), f.text_field(:base_tool_name, :value => @base_tool_name, :readonly => true) %>
  10 +
  11 + <% f.fields_for :metric do |m| %>
  12 +
  13 + <% @metric.language.each do |language| %>
  14 + <%= m.hidden_field :language, :multiple => true, :value => language %>
  15 + <% end %>
  16 +
  17 + <%= m.hidden_field "scope", :value => @metric.scope %>
  18 +
  19 + <p>
  20 + <%= m.label :name, "Metric Name:" %>
  21 + <%= @metric.name %>
  22 + <%= m.hidden_field "name", :value => @metric.name %>
  23 + </p>
  24 + <% m.label :description, "Description:" %>
  25 + <% @metric.description %>
  26 + <% m.hidden_field "description", :value => @metric.description %>
  27 + <% end %>
  28 +
  29 + <%= required labelled_form_field _('Code:'), f.text_field(:code) %>
  30 +
  31 + <%= required labelled_form_field _('Aggregation Form:'),
  32 + f.select(:aggregation_form, MezuroPlugin::Helpers::ContentViewerHelper.aggregation_options) %>
  33 +
  34 + <%= required labelled_form_field _('Weight:'), f.text_field(:weight) %>
  35 +
  36 + <%= required labelled_form_field _('Reading Group:'),
  37 + f.select(:reading_group_id, @reading_group_names_and_ids) %>
  38 +
  39 + <p>
  40 + <%= f.submit "Add" %>
  41 + </p>
  42 +
  43 +<% end %>
  44 +