機能 #81
未完了Redmine 4.0でglossary pluginを動くようにする
50%
説明
Redmine 4.0(2018-04-22時点で開発中)でglossary pluginが動くかどうかを確かめるため、開発ブランチにglossary pluginを入れてみたところ、エラーとなった(次の日記参照)。
redmine trunkを落としてglossary pluginが動くか試してみる
Redmine 4.0で動かすための修正方法(最低限)を調査し、動作するための修正を見出す。
終了条件:動作するための修正を見出す。あきらめる。
高橋 徹 さんがほぼ7年前に更新
rake redmine:plugins:migrate
すると次のエラー
NoMethodError: undefined method `alias_method_chain' for ActionView::Helpers::AssetTagHelper:Module Did you mean? alias_method plugins/redmine_glossary/lib/glossary_asset_tag_helper_patch.rb:20:in `<module:AssetTagHelper>'
alias_method_chainはRails 5.1では削除されていおり、Module#prepend で書き換えろとあります。ところが、書き換え方はさっぱり不明(alias_method_chainもよく分からず)。
まずは理解しないまま当てずっぽうな変更を実施。
--- a/lib/glossary_asset_tag_helper_patch.rb
+++ b/lib/glossary_asset_tag_helper_patch.rb
@@ -1,8 +1,8 @@
module ActionView
module Helpers
- module AssetTagHelper
- def javascript_include_tag_with_glossary(*sources)
- out = javascript_include_tag_without_glossary(*sources)
+ module AssetTagHelperIncludeTag
+ def javascript_include_tag(*sources)
+ out = super(*sources)
if sources.is_a?(Array) and sources[0] == 'jstoolbar/textile'
out += javascript_tag <<-javascript_tag
jsToolBar.prototype.elements.termlink = {
@@ -17,7 +17,9 @@ javascript_tag
end
out
end
- alias_method_chain :javascript_include_tag, :glossary
+ end
+ module AssetTagHelper
+ prepend AssetTagHelperIncludeTag
end
end
end
高橋 徹 さんがほぼ7年前に更新
先の当てずっぽう修正後、rake redmine:plugins:migrate
すると次のエラー
Directly inheriting from ActiveRecord::Migration is not supported. Please specify the Rails release the migration was written for: class CreateTerms < ActiveRecord::Migration[4.2] vendor/bundler/ruby/2.4.0/gems/activerecord-5.1.6/lib/active_record/migration.rb:525:in `inherited' plugins/redmine_glossary/db/migrate/001_create_terms.rb:1:in `<top (required)>'
これは難題だ・・・
Redmine 4.0開発版(trunk)で、新規プラグインを作成し、モデルを生成し、そのmigrateの雛形を確認すると
class CreateTerms < ActiveRecord::Migration[5.1] def change create_table :terms do |t| end end end
となっていた。どうやら、RailsのバージョンがMigrationの後ろに付く模様。そこで、db/migrate/の下にあるマイグレーションコードの継承クラス名を、ActiveRecord::Migration
からActiveRecord::Migration[5.1]
に修正。
diff --git a/db/migrate/001_create_terms.rb b/db/migrate/001_create_terms.rb
index c8cb3b9..3974adc 100644
--- a/db/migrate/001_create_terms.rb
+++ b/db/migrate/001_create_terms.rb
@@ -1,4 +1,4 @@
-class CreateTerms < ActiveRecord::Migration
+class CreateTerms < ActiveRecord::Migration[5.1]
def self.up
# CreateTermCategories
create_table :term_categories, :force => true do |t|
diff --git a/db/migrate/002_create_glossary_styles.rb b/db/migrate/002_create_glossary_styles.rb
index 512477c..4e9e55f 100644
--- a/db/migrate/002_create_glossary_styles.rb
+++ b/db/migrate/002_create_glossary_styles.rb
@@ -1,4 +1,4 @@
-class CreateGlossaryStyles < ActiveRecord::Migration
+class CreateGlossaryStyles < ActiveRecord::Migration[5.1]
def self.up
create_table :glossary_styles do |t|
t.column :show_desc, :boolean, :default => false
diff --git a/db/migrate/003_terms_add_columns.rb b/db/migrate/003_terms_add_columns.rb
index af949fe..cc3d873 100644
--- a/db/migrate/003_terms_add_columns.rb
+++ b/db/migrate/003_terms_add_columns.rb
@@ -1,4 +1,4 @@
-class TermsAddColumns < ActiveRecord::Migration
+class TermsAddColumns < ActiveRecord::Migration[5.1]
def self.up
add_column :terms, :tech_en, :string, :default => ''
プラグインのマイグレーションを実行すると、エラーは解消、ただしDEPRECATION WARNINGが出ている。
DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 5.2. (called from instance_eval at trunk/config/routes.rb:377)
おそらく、routes.rbの次の記述(URLパスの中に:action
が含まれる)が警告対象
match 'projects/:project_id/glossary/:action', :controller => :glossary, :via => :all
高橋 徹 さんがほぼ7年前に更新
一応マイグレーションは終わったので(alias_method_chainの書き換えは仮のまま)、実行したところプロジェクトメニューの[用語集]をクリックすると次のエラーが発生した。
undefined method `before_filter' for GlossaryController:Class : plugins/redmine_glossary/app/controllers/glossary_controller.rb:7:in `<class:GlossaryController>' plugins/redmine_glossary/app/controllers/glossary_controller.rb:2:in `<top (required)>'
該当コードは次
class GlossaryController < ApplicationController
menu_item :glossary
unloadable
layout 'base'
before_filter :find_project, :authorize
before_filter :find_term, :only => [:show, :edit, :destroy]
before_filter :retrieve_glossary_style, :only => [:index, :show, :show_all, :import_csv_exec]
before_filterは、Rails 5ではbefore_actionに単純に書き換えればよいようです。
--- a/app/controllers/glossary_controller.rb
+++ b/app/controllers/glossary_controller.rb
@@ -4,9 +4,9 @@ class GlossaryController < ApplicationController
unloadable
layout 'base'
- before_filter :find_project, :authorize
- before_filter :find_term, :only => [:show, :edit, :destroy]
- before_filter :retrieve_glossary_style, :only => [:index, :show, :show_all, :import_csv_exec]
+ before_action :find_project, :authorize
+ before_action :find_term, :only => [:show, :edit, :destroy]
+ before_action :retrieve_glossary_style, :only => [:index, :show, :show_all, :import_csv_exec]
helper :attachments
include AttachmentsHelper
高橋 徹 さんがほぼ7年前に更新
#81-5 の修正をしてサーバーを再起動(再起動しないと、LoadError
Unable to autoload constant GlossaryController というエラーが出る)すると、プロジェクトメニューの[用語集]をクリックすると別なエラーが発生した。
NoMethodError in GlossaryController#index undefined method `attr_accessible' for #<Class:0x00007fffdb947f18> belongs_to :project attr_accessible :groupby def grouping? case groupby
#81-6 と同じくattr_accessibleがエラーとなった。対処方法をググってみると、「ストロングパラメータ」なるものを使う模様。まずモデルからattr_accessible行を削除、コントローラーにストロングパラメータの記述(privateなメソッドでモデル名_paramsを定義、params.require(モデル名).permit(属性名) を呼ぶ)をするようです。
まず、GlossaryStyleモデルからattr_accessibleを削除
--- a/app/models/glossary_style.rb
+++ b/app/models/glossary_style.rb
@@ -11,8 +11,6 @@ class GlossaryStyle < ActiveRecord::Base
belongs_to :project
- attr_accessible :groupby
-
def grouping?
GlossaryStylesControllerコントローラーにストロングパラメータの設定を追加
--- a/app/controllers/glossary_styles_controller.rb
+++ b/app/controllers/glossary_styles_controller.rb
@@ -58,4 +58,10 @@ class GlossaryStylesController < ApplicationController
add_search_params(newparams)
redirect_to(newparams)
end
+
+ private
+
+ def glossary_style_params
+ params.require(:glossary_style).permit(:groupby)
+ end
end
ここで、誰がglossary_style_paramsを呼ぶのかが不明。要調査。
⇒ コントローラーにcreateメソッドを定義し、その中でストロングパラメータのメソッドを呼ぶ模様。
def create
GlossaryStyle.create(glossary_style_params)
end
ということなのかな?よく分からず。
もう一つTermモデルとGlossaryControllerコントローラーにも同じくattr_accessibleの修正をした。
--- a/app/models/term.rb
+++ b/app/models/term.rb
@@ -19,8 +19,6 @@ class Term < ActiveRecord::Base
:type => 'terms',
:url => Proc.new {|o| {:controller => 'glossary', :action => 'show', :id => o.project, :term_id => o.id} }
- attr_accessible :project_id, :category_id, :author, :name, :name_en, :datatype, :codename, :description,
- :rubi, :abbr_whole
--- a/app/controllers/glossary_controller.rb
+++ b/app/controllers/glossary_controller.rb
@@ -177,6 +177,10 @@ class GlossaryController < ApplicationController
private
+ def term_params
+ params.require(:term).permit(:project_id, :category_id, :author, :name, :name_en, :datatype, :codename, :descriptio
n, :rubi, :abbr_whole)
+ end
+
ちゃんとした修正方法を見出す必要がある。
高橋 徹 さんが6年以上前に更新
#81-3 の内容について追加情報
alias_method_chainでやろうとしていることは、wikiツールバーを表示するJavaScriptを読み込むタイミングをインターセプトして用語リンクのマクロを挿入するボタンを追加すること。
JavaScriptの読み込みタイミングは、javascript_include_tagメソッドを引っ掛け、その引数(JavaScriptファイルのパス)がjstoolbar/textileである、すなわちRedmineのpublic/javascripts/jstoolbar/textile.js を読み込むときとしている。
javascript_include_tagメソッドは、ファイルapp/helpers/application_helper.rbの中でModule ApplicationHelperの特異メソッドとして定義されている。
また、Redmine 4.0のコード内でjavascript_include_tagを呼び出す箇所を見て回ったところ、textile.jsを指定しているコードは見つからず、近そうな次のJavaScriptファイルを指定している箇所が見つかった。
- jstoolbar/jstoolbar-textile.min
- jstoolbar/lang/jstoolbar_<言語コード>.js
http://www.redmine.org/projects/redmine/repository/revisions/10095
修正はここで入っている。修正前は、jstoolbar/textileを指定していたが、修正後はjstoolbar/jstoolbar-textile.minを指定している。
コメントを見ると、jstoolbar.jsとtextile.jsをマージして整理したものがjstoolbar-textile.min.jsとのこと。
よって、手の入れ方を変える必要がありそうだ。
高橋 徹 さんが6年以上前に更新
alias_method_chain を prepend に置き換える¶
Wiki編集エリアに表示するツールバーは、JavaScriptで記述され、<Redmine基点>/public/javascripts/jstoolbar/ディレクトリ下にファイルが置かれています。このJavaScriptファイルを読み込むタイミングに割り込み、用語マクロを展開するボタンを1つ追加する処理を入れるものです。
JavaScriptを読み込むメソッドはjavascript_include_tagですが、定義場所を調べると2つあり、Ruby on RailsのActionViewの中と、Redmineのapplication_helperの中となります。Redmineの定義はRuby on Railsのそれをオーバーライドして追加処理(プラグインディレクトリのassets下にあるJavaScriptを読む)を入れたものです。
Glossaryプラグインのオリジナルの処理(alias_method_chain)は、Ruby on Rails側のjavascript_include_tagメソッドの処理をフックしていますが、今後を考えるとRedmineのjavascript_include_tagメソッドに対してprependするのがよいと思うのでそのように修正をしていきます。
Redmine本体のjavascript_include_tagメソッドは、app/helpers/application_helper.rb の中でmodule ApplicationHelperに定義されています。
Ruby on Railsのjavascript_include_tagメソッドは、gemのactionview内に、lib/action_view/helpers/asset_tag_helper.rb の中でmodule ActionView::Helpers::AssetTagHelperに定義されています。
- ファイル名の変更
パッチ先の場所がactionview(モジュールActionView::Helpers::AssetTagHelper)からredmine(モジュールApplicationHelper)に変わるので、ファイル名もglossary_asset_tag_helper_patch.rbからglossary_application_helper_patch.rbに変更します。
- prependするモジュール名は、prepend先のモジュール名ApplicationHelperの接頭辞にGlossaryを付けた
GlossaryApplicationHelper
とします。module GlossaryApplicationHelper def javascript_include_tag(*sources) out = super(*sources) if sources.is_a?(Array) and sources[0] == 'jstoolbar/jstoolbar-textile.min' out += javascript_tag <<-javascript_tag jsToolBar.prototype.elements.termlink = { type: 'button', title: '#{l(:label_tag_termlink)}', fn: { wiki: function() { this.encloseSelection("{{term(", ")}}") } } } javascript_tag out += stylesheet_link_tag 'termlink', :plugin => 'redmine_glossary' end out end end ApplicationHelper.prepend GlossaryApplicationHelper
- ファイル名を変更したので、init.rbのrequire文を修正します。
-require 'glossary_asset_tag_helper_patch' +require 'glossary_application_helper_patch'
Glossaryプラグインを使用しないプロジェクトのWiki編集に用語リンクボタンが表示されるのも今一なので、表示条件をGlossaryプラグインを使用するプロジェクトのWiki編集時に変更します。
def javascript_include_tag(*sources)
out = super(*sources)
- if sources.is_a?(Array) and sources[0] == 'jstoolbar/jstoolbar-textile.min'
+ if @project.try!(:module_enabled?, 'glossary') and sources.is_a?(Array) and sources[0] == 'jstoolbar/jstoolbar-textile.min'
out += javascript_tag <<-javascript_tag
高橋 徹 さんが6年以上前に更新
redmine:plugins:migrateタスクを実行するとエラー(プラグインによらず、プラグインがなくても)
Migrating redmine_glossary (Redmine Glossary Plugin)... rails aborted! NoMethodError: undefined method `migrate' for Redmine::Plugin::Migrator:Class /work/redmine/lib/redmine/plugin.rb:482:in `migrate_plugin' /work/redmine/lib/redmine/plugin.rb:454:in `migrate' /work/redmine/lib/redmine/plugin.rb:468:in `block in migrate' /work/redmine/lib/redmine/plugin.rb:467:in `each' /work/redmine/lib/redmine/plugin.rb:467:in `migrate' /work/redmine/lib/tasks/redmine.rake:135:in `block (3 levels) in <top (required)>' :
ActiveRecord::Migrator::migrate(a, b) を呼ぼうとしているが、Rails 5.1まであったがRails 5.2で削除されている。
Redmineのチケットに登録あり
https://www.redmine.org/issues/28934
パッチとテストコードが添付されているので、近々マージされると思われます。
高橋 徹 さんが6年以上前に更新
GlossaryControllerのnewメソッドがどのタイミングで呼ばれどのようにふるまうのかが謎。
Ruby on Railsの教科書的な作りでは、- HTTP Client から new リクエスト(GET)でコントローラーのnewメソッド起動
- コントローラーのnewメソッド内で空のモデルをnew
- new.html.erb テンプレートからフォームを含むHTMLをHTTP Clientに返却
- HTTP Client からモデルリソースへ設定する内容を含むフォームをサブミット (POST)
- サブミットによりコントローラーのcreateメソッド起動
- フォームのパラメーターをモデルにセットしモデルを永続化(save)
- モデルの詳細表示(showアクション)へリダイレクト
- コントローラーのshowメソッド起動
- show.html.erb テンプレートから新たに作成されたモデルの詳細表示HTMLをHTTP Clientに返却
- HTTP Client から new リクエスト(GET)でコントローラーのnewメソッド起動
- コントローラーの中でリクエストが GETまたはXHR(AJAX)か判別
- 偽であれば
- モデルを永続化(save)
- 続けて作成であれば 再びコントローラーのnewへリダイレクト(GET)
- おしまいであればコントローラーのshowへリダイレクト(GET)
- 真であれば
- new.html.erb テンプレートからフォームを含むHTMLをHTTP Clientに返却
- 偽であれば
というちょっと複雑(ダブルミーニング)なメソッドとなっています。
GlossaryStylesControllerも変則的なアクションになっていて- search アクションはGETで呼ばれる
- edit アクションはPOSTで呼ばれる
Railsのルーティング設定で、リソース定義を使うとeditアクションはGETとなります。
用語集プラグインのコントローラーの作り方をRailsの標準形式に変えたいところですが、それはRedmine 4.0移植が済んだ後のリファクタリングで実施することとします。
高橋 徹 さんが6年以上前に更新
リンクエラー
unable to convert unpermitted parameters to hash発生個所は次
- app/views/glossary/index.html.erb
<%= f.link_to 'CSV', :url => params %>
paramsの内容は次
{"controller"=>"glossary", "action"=>"index", "project_id"=>"glossarytest"}
エラーメッセージでぐぐると、Rails 5から、パラメーターがハッシュ継承ではなくなったとあります。また、permissionがtrueでないと次のパスに渡せないとありました。
https://qiita.com/DialBird/items/28324de658773b0b34a0
そこで、ハッシュ化しpermissionを与えるコードを明示的に記述します。
- <%= f.link_to 'CSV', :url => params %>
+ <%= f.link_to 'CSV', :url => params.permit!.to_h %>
高橋 徹 さんが6年以上前に更新
ストロングパラメーターの実装に関して、HTTPリクエストパラメーターを受け取ってカテゴリモデルTermCategoryを生成するのは、教科書的にはTermCategoriesControllerであるが、本プラグインの実装では、GlossaryControllerのadd_term_categoryメソッドで生成している。
GlossaryControllerは肥大化しているので、いずれadd_term_categoryをTermCategoriesControllerに移動させる(対応するビューも)が、今回はTermCategoryを生成するストロングパラメーターの実装をGlossaryControllerにも記述する。
さて、GlossaryControllerのadd_term_categoryであるが、これもHTTPのGETメソッドとPOSTメソッドで起動され、それぞれで異なるふるまいをするダブルミーニングな実装となっている。
TermCategoriesControllerのeditメソッドもHTTPのGETとPATCHのダブルミーニングとなっている。
高橋 徹 さんが6年以上前に更新
削除のルーティング設定について
もとのroutes.rbには、次のように削除のルーティング設定が記載されている。
match 'projects/:project_id/glossary/destroy', :to => 'glossary#destroy', :via => [ :delete ]
これを、matchを使わないよう書き換えたが
delete '/projects/:project_id/glossary/:id/destroy', to: 'glossary#destroy'
実行すると次のエラーとなった。No route matches [POST] "/projects/glossarytest/term_categories/destroy"
削除のリンクが、HTTPのDELETEメソッドではなくPOSTメソッドで出ている模様。
元のルーティング設定をよくよく見ると
match 'projects/:project_id/glossary/:action', :controller => :glossary, :via => :all
というワイルドカードルーティング設定が存在している。おそらく、こちらが効いていたのかと思われる。削除リンクの定義箇所を調べてみると、
- app/views/glossary/_index_in_category.html.erb
<%= link_to_if_authorized(image_tag('delete.png'), {:action => 'destroy', :project_id => @project, :id \=> term}, :confirm => l(:text_are_you_sure), :method => :post, :title => l(:button_delete)) %>
とHTTPメソッドがPOSTと指定されている。
ここは、Redmine 4.0対応上は現行踏襲を優先とするが後日書き換えることとする。
高橋 徹 さんが6年以上前に更新
テストについても考慮していく必要がある。
まず、現状でテストを実行してみるとどうなるか確認
$ bundle exec rails redmine:plugins:test NAME=redmine_glossary RAILS_ENV=test rails aborted! LoadError: cannot load such file -- /work/test/test_helper :
次のブログに同じ問題と解決策が掲載されていた。
http://d.hatena.ne.jp/kk_Ataka/20140224/1393251209
Redmine 1.x までは、vendor/plugin/下にプラグインディレクトリがあったが、Redmine 2.0からはplugin/下にプラグインディレクトリがあります。
-require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
+require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper')
階層が変わったので、その修正を入れます。
高橋 徹 さんが6年以上前に更新
Redmine 4以降で動作するプラグインを作る場合、init.rbのrequires_redmineにバージョンを指定することになるが、trunkのredmineは3.4.6のままなので、テスト時にredmineのバージョンを4.0.0に修正したい。
バージョンを定義するファイルを探したところ
- lib/redmine/version.rb にあり
module Redmine # @private module VERSION MAJOR = 3 MINOR = 4 TINY = 6 # Branch values: # * official release: nil # * stable branch: stable # * trunk: devel BRANCH = 'devel'
高橋 徹 さんが6年以上前に更新
- カテゴリ を Redmine にセット
テスト実行時に次の警告メッセージが表示されます。
$ bundle exec rails redmine:plugins:test:units RAILS_ENV=test DEPRECATION WARNING: Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer` set to false is deprecated. SQLite databases have used 't' and 'f' to serialize boolean values and must have old data converted to 1 and 0 (its native boolean serialization) before setting this flag to true. Conversion can be accomplished by setting up a rake task which runs ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1) ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0) for all models and all boolean columns, after which the flag must be set to true by adding the following to your application.rb file: Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true (called from <top (required)> at /work/redmine/config/environment.rb:14)
Rails 5.2で入った次の修正によるものです。
https://github.com/rails/rails/pull/29699
用語集プラグインでは、テーブルglossary_stylesでboolean型を使用しています。
高橋 徹 さんが6年以上前に更新
ユニットテスト(Model)を実施して問題発見
- app/models/term_category.rb
Term.update_all("category_id = #{reassign_to.id}", "category_id = #{id}")
このコードが次のエラーとなる。
ArgumentError: wrong number of arguments (given 2, expected 1)
Rails 5.2のドキュメントによると、
Method: ActiveRecord::Relation#update_all
#update_all(updates) ⇒ Object
引数updatesは、文字列、配列、ハッシュのいずれかで、SQL文の部分集合を表す
とあるので、2つの引数を指定するのは(ハッシュのブラケット省略出ない限り)エラー。
高橋 徹 さんが6年以上前に更新
用語のユニットテスト実施メモ
Termクラスではvalidationを次のように指定している。
validates_presence_of :name, :project
TermTestクラスでfixturesの指定は最初次のようにしていた。
plugin_fixtures :terms
terms.ymlには、project_idで値を指定していたが、validationチェック(valid?メソッド)ではprojectがナイトのエラーとなっていた。どうやら、project_idに何か値が入っているだけではだめで、project_idからprojectインスタンスが生成できないとならないらしい。
そこで、fixturesの指定にprojectを追加したところ、テストが進んだ。
fixtures :projects plugin_fixtures :terms
高橋 徹 さんが6年以上前に更新
コントローラーのテスト(ActiveController::TestCase継承で)
まず、一番単純なモデルであるカテゴリのコントローラーのテストを行う。
indexアクションのテストが実行できるまでの流れをはてな日記に記載。
http://d.hatena.ne.jp/torutk/20180721/p1
高橋 徹 さんが6年以上前に更新
glossary_styles_controller#edit のロジックが複雑な件について
anonymous | params[:clear]指定あり | session[:glossary_style] = nil |
params[:clear]指定なし | session[:glossasy_style] = params[:glossary_style] |
glossary_styles_controller#edit で次の記述があるが
unless params[:glossary_style_id].blank?
@glossary_style = GlossaryStyle.find_by(:user_id => User.current.id)
end
params[:glossary_style_id]が存在するとき、ユーザーIDで検索するので判定ロジックが逆ではなかろうか?
editアクションを呼び出すビューは、app/views/glossary_styles/_form.html.erb にあり。
フォームのパラメータは
キー名 | 入力種類 | 取りうる値 |
---|---|---|
show_desc | チェックボックス | 0, 1 |
project_scope | 選択リスト | 0(ProjectCurrent), 1(ProjectMine), 2(ProjectAll) |
groupby | ラジオボタン | 0(GroupByNone), 1(GroupByCategory), 2(GroupByProject) |
clear | サブミット(クリア) | 'clear' ? |
HTTPリクエストのパラメータ例
<ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"FVBvc5KZVDQ66yQ4v75+gz3FopWzqM/QRrsSAkVmLRwgdZajlHyoz6SlR0pQXbZsHiMPMUi9iyp/bcOfuihQKg==", "glossary_style"=>{"show_desc"=>"0", "project_scope"=>"0", "groupby"=>"1", "sort_item_0"=>"", "sort_item_1"=>""}, "commit"=>"表示", "project_id"=>"glossary-test", "controller"=>"glossary_styles", "action"=>"edit"} permitted: false>
高橋 徹 さんが6年以上前に更新
glossary_controller のテストで nilに対するempty?呼び出しで例外発生
- fixtures/terms.yml
name_en: codename:
このfixtureの記述は、データベース上値がNULLとなる。
スキーマ上、termsテーブルのname_enカラムとcodenameカラムは、NOT NULL制約はないが、DEFAULT ''となっている。コントローラーのコードは、レコードの値がNULLを考慮していない。どうしたものかと考え、fixturesにデフォルト値を記載することとした。なお、datatypeがfixtureにないので合わせて追加
- name_en:
- codename:
+ name_en: ''
+ codename: ''
+ datatype: ''