DRY CRUDでコードの繰り返しをなくす

Ruby on Railsフレームワークは単に私を魅了しますが、最近まで、CRUDコントローラーの生成はちょっとした挑戦でした。

ほとんど常に、ソート、フィルタリング、ページネーションを使用してリストを実装する必要がありましたが、これをRailsで実現する標準的な方法は見つかりませんでした。 私はいくつかのオプションを試しましたが、単一のオプションでは満足しませんでした。

長い間、私はYiiフレームワークで気に入ったCGridViewウィジェットに似たものを見つけることができませんでした。 私は自分の自転車を書く必要があるとほぼ納得しましたがDRY CRUDに出会い、その使用経験を共有したいと思います。 誰かが便利だと思うかもしれませんし、誰かがもっと適切なツールを教えてくれるかもしれません。

設置


DRY CRUDは、ジェネレーターを使用してプロジェクト内に独自のコントローラークラスを作成するgemです。この生成後、gemをオフにし、必要に応じて生成されるコードを変更できます。
インストールするには、Gemfileでgemを指定するだけです
gem 'dry_crud', '= 1.7.0' 

走る
 bundle install 

およびジェネレーター
 rails generate dry_crud --templates haml --tests rspec 


機会のデモンストレーション


デモンストレーションとして、1対多の関係で接続された2つのユーザーモデルとポストモデルからアプリケーションを作成しました。
 rails generate model User name:string email:string pass:string rails generate model Post author_id:integer title:string content:text is_draft:boolean 

人間にとってよりわかりやすい表示のために、 to_sメソッドが定義され、次のモデルコードが取得されました。
 #user.rb class User < ActiveRecord::Base attr_accessible :email, :name, :pass has_many :posts def to_s "#{name}" end end #post.rb class Post < ActiveRecord::Base attr_accessible :user_id, :content, :is_draft, :title belongs_to :user def to_s "#{title}" end end 

/ app / controllersフォルダーにコントローラーファイルを作成し、 CrudControllerから継承するだけで十分です。 また、フィルタリングを提供する列を指定することもできます。
 #users_controller.rb class UsersController < CrudController self.search_columns = [:name, :email] end 

それだけです。より複雑な機能が必要になるまで、ビュー用のフォルダーを作成する必要さえありません。 アプリケーションを起動し、並べ替え(クリック可能な列)とフィルタリング( コントローラーにself.search_columnsがインストールされている場合)およびページネーションを最小限の労力でねじ込むことができ、フィルターと並べ替えの両方と互換性のある動作CRUDを取得します。


編集フォームも失望せず、各フィールドのタイプを決定し、boolean、string、textフィールド、およびbelongs_toリンクに適切なコントロールを使用します。

そしてもちろん、これはすべてカスタマイズできます!

Twitterブートストラップ接続

私のプロジェクトの多くはTwitterブートストラップを使用しており、DRY CRUDの適応は非常に簡単です。twitter -bootstrap-railsgemを接続し、ジェネレーターでインストールするだけです。
 rails generate bootstrap:install less 

app / views / layouts / crud.html.hamlおよび/app/assets/stylesheets/sample.scssを削除し、 /app/views/layouts/ application.htmlを書き換えます 。 興味がある人は誰でもプロジェクトのソースコードを見ることができます。
その結果、認識可能なデザインが得られます。


列を非表示

たとえば、すべてのコントローラーでcreated_atおよびupdated_at列を非表示にする必要がある場合は、基本クラスヘルパーを変更するだけです。
 #/app/helpers/list_helper.rb def default_attrs attrs = model_class.column_names.collect(&:to_sym) attrs - [:id, :position, :password, :created_at, :updated_at] #<   end 


列セットを変更

ユーザーで、 パス列を非表示にしてcreated_atを追加します。 これを行うには、フォルダー/ app / views / usersを作成し、共有部分/app/views/crud/_form.html.hamlをそこにコピーします
最初の唯一のrow = crud_tableする列のリストを追加します。
 = crud_table :name, :email, :created_at 

結果:


セルの内容のフォーマット

デフォルトでは、投稿の内容は完全に表示されます:

100文字にトリミングするには、ヘルパーでformat_メソッドを作成するだけです
 #/app/helpers/post_helper.rb module PostHelper def format_content(post) truncate(post.content, :length => 100, :omission => '...') end end 

結果:


ローカリゼーション

レールL18nの機能を使用して、ビューを変更せずにフィールドのラベルを変更できます。 これを行うには、デフォルトの言語を設定します。
 #/config/application.rb .... module DryCrudSample class Application < Rails::Application ... I18n.default_locale = :ru end end 


言語ファイルを生成するために、gem「l18n_generator」を使用しました
 #Gemfile group :development do gem 'i18n_generators' end 


rails-i18nリポジトリからロケールファイルをダウンロードします
 rails generate i18n_locale ru 


DRY CRUDのインストール中に生成された翻訳ファイル/config/locales/en_crud.ymlru_crud.ymlにコピーして翻訳します。
モデル用のYAMLファイルを生成します
 rails generate i18n_translation ru 

ファイル/config/locales/translation_ru.ymlを取得しますこのファイルの名前はru_models.ymlに変更します
モデルのフィールドに必要な名前を書くだけです

アプリケーションを再起動すると、ローカライズされたインターフェイスが表示されます。


編集後の動作の変更

写真が終わり、より深い調整が始まります。
デフォルトでは、エントリを正常に作成または編集した後、このエントリを表示するためのリダイレクトが発生します(「show」アクション)。「index」ソリューションへのリダイレクトに精通していました。
 #/app/controllers/crud_controller.rb def update(options = {}, &block) assign_attributes updated = with_callbacks(:update, :save) { entry.save } #respond_with(entry, options.reverse_merge(:success => updated), &block) #<-  respond_with(entry, options.reverse_merge(:success => updated, :location=> index_url), &block) # end 

createメソッドでも同様の置換が必要でした。

次に、プロジェクトでレコードを編集した後、独自の編集フォームに戻る必要がありました。 これをPostsコントローラーに実装するには、目的のURLを転送するためのupdateメソッドを再定義するだけです。
 #/app/controllers/posts_controller.rb def update super location: edit_post_path(params[:id]) end 


アクション列にボタンを追加する

プロジェクトの1つは、記録クローン機能を実装する必要がありました。 私が理解しているように、この機能はデフォルトでは欠落しているため、次のように実装しました。 たとえば、Postは、最初にリソースルートで新しいアクションを定義しました。
 #routes.rb resources :posts do get :clone, :on => :member end 

このアクションはidコピーされたレコードのidを取得し、フィールドにすでに入力されている作成フォームを表示する必要があります。 createアクションでフォームを送信しcreate
モデルのクローンコードを基本クラスに配置しました。
 #/app/controllers/crud_controller.rb def duplicate_entry() set_model_ivar( find_entry.dup() ) end 


ボタン生成コードはヘルパーにあります:
 #/app/helpers/crud_helper.rb def action_col_clone(table, &block) action_col(table) do |e| link_table_action('list-alt', action_path(e, &block)) #       end end 


ビューの列の場所に新しいボタンを追加するためのコード:
 #/app/views/posts/_list.html.haml = crud_table :title, :content, :is_draft do |t| - action_col_clone t do |e| - clone_post_path e #     

すべてがうまくいきました。 追加された機能は2つだけで、プロジェクト全体で1行で「クローン」ボタンを追加できるようになりました。

おわりに


実際、「deep_cloneable」gemを使用して、ActiveRecordとその依存関係を複製できます。 また、フォームでは、レコード自体だけでなく、「has_many」を介して関連するレコードも編集できます。 また、フィルタをより複雑にするために、1つのテキストフィールドだけでなく、複数の選択を行います。 そして、これらはすべて非常に単純で、ドキュメントに部分的に記載されており、ソースコードの研究によって部分的に理解されています。

DRY CRUDは非常に柔軟で強力であるという結論に達しました。

プロジェクト内にある「ソースコード」を編集しなければならない変更を加えるのは少し恥ずかしいことですが、これはおそらく著者による更新の使用を複雑にする可能性があります。 しかし、これまでのところ私はそのような必要性に遭遇したことがなく、変更の量が少ないため、これは実際の問題を構成します。

参照資料


gem DRY CRUDの手順
GitHubサンプルソース

Source: https://habr.com/ru/post/J175887/


All Articles