機能 #88
完了機能 #83: Redmine Glossaryプラグインをリファクタリングする
acts_as_listをacts_as_positionedで置き換え
100%
説明
acts_as_listはRedmine 4.0で除外されたので、Redmine 4.0対応[#81]では外部gemとしてacts_as_listを追加指定した。
Redmine 4.0本体には、lib/redmine/acts/positioned.rb ファイルでacts_as_positionedが提供される(?)ので、これを利用するように変更する。
Redmine本体のモデルクラスでもいくつかでacts_as_positionedを使用している。Board, CustomField, IssueStatus, Role, Tracker
高橋 徹 さんが6年以上前に更新
acts_as_positioned の使い方調査~ Boardモデルでの利用形態
- app/models/board.rb で
class Board < ActiveRecord::Base : acts_as_positioned :scope => [:project_id, :parent_id] : safe_attributes 'name', 'description', 'parent_id', 'position' : def self.board_tree(boards, parent_id=nil, level=0) tree = [] boards.select {|board| board.parent_id == parent_id}.sort_by(&:position).each do |board| tree << [board, level] tree += board_tree(boards, board.id, level+1) end
まず、モデルクラスにおいて、acts_as_positioned
を呼び出す。スコープが全体でない場合は引数ハッシュにscopeキーで範囲を指定する。
データベース(スキーマ)にカラムpositionを型をintegerで追加する。
高橋 徹 さんが6年以上前に更新
acts_as_positioned の使い方調査~Trackerでの利用形態
- app/models/tracker.rb
class Tracker < ActiveRecord::Base : acts_as_positioned : scope :sorted, lambda { order(:position) } : safe_attributes 'name', : 'position', : def <=>(tracker) position <=> tracker.position end
Trackerモデルでは、
- acts_as_positioned 呼び出し
- scope :sorted で、カラムpositionの順番で並べ替え(order)
- <=>演算子オーバーロードでTrackerインスタンス間のposition比較
を実装している。
TrackersControllerからは、モデルTrackerのscope :sortedを呼び出し
Trackerビュー(一覧表示)では、
<table class="list trackers">
:
<% for tracker in @trackers %>
:
<td class="buttons">
<%= reorder_handle(tracker) %>
<%= delete_link tracker_path(tracker) %>
</td>
:
<% end %>
</tbody>
</table>
:
<%= javascript_tag do %>
$(function() { $("table.trackers tbody").positionedItems(); });
<% end %>
<%= reorder_handle(tracker) %>
で並べ替え操作用のボタンを表示<%= javascript_tag do %> ...
で並べ替え操作時の処理
reorder_handleメソッドは、app/helpers/application_helper.rb に定義
def reorder_handle(object, options={})
data = {
:reorder_url => options[:url] || url_for(object),
:reorder_param => options[:param] || object.class.name.underscore
}
content_tag('span', '',
:class => "sort-handle",
:data => data,
:title => l(:button_sort))
end
高橋 徹 さんが6年以上前に更新
並べ替え操作をすると、並び替え対象行の並び替えアイコンがぐるぐるになって、しばらくすると「0」だけ書かれたダイアログが表示される。
管理 > トラッカーで表示されるトラッカーを並べ替え操作したときの通信を見ると(Firefoxで、Ctrl + Shift + Iで開発画面を表示、ネットワークで状況確認)
要求URL: http://server:3000/trackers/2
要求メソッド: PUT
ステータスコード:200
フォームデータは、tracker[position]: 2
Content-Type: text/javascript
用語カテゴリの並び替えでは、
要求URL: http://server:3000/projects/glossary-test/glossary_categories/3
要求メソッド: PUT
ステータスコード: 302
フォームデータは、glossary_category[position]: 1
Content-Type: text/html; charset=utf-8
ということで、コントローラーのupdateアクションでは並び替え操作で呼ばれるときは応答がJavaScriptになるらしい。TrackersControllerのupdateメソッドを見ると
def update
@tracker = Tracker.find(params[:id])
@tracker.safe_attributes = params[:tracker]
if @tracker.save
respond_to do |format|
format.html {
flash[:notice] = l(:notice_successful_update)
redirect_to trackers_path(:page => params[:page])
}
format.js { head 200 }
end
else
respond_to do |format|
format.html {
edit
render :action => 'edit'
}
format.js { head 422 }
end
end
end
となって、フォーマットがHTMLかJS(JavaScript)かで処理を分けている。