0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

#初めに
Railsでmodelにスコープを書くことがあるのですがスコープの数が多くなりすぎることがあります。

それで動的にスコープが定義出来たらと思って自分で試してみました。

#具体例

具体的な例として記事に言語の設定があるとします。

モデルはこんな感じ

erdplus-diagram.png

そんでこのlangはinteger型でenumを使います

なのでmodels/article.rbには

article.rb
class DataCollect < ApplicationRecord
    enum lang: {ja: 0, en: 1, ar: 2, de: 3,el: 4, eo: 5, es: 6, fr: 7}
end

こんな感じに設定します

これでarticleを作成するときにlangを設定してあげれはその記事の言語がわかるようになります。

#scopeを作成

scopeを作成するときに例えば

Article.ja.all

で日本語の記事がとれるようにするためにはmodels/article.rbに

scope :ja, -> {where(lang: :ja)}

とすれば実装できます。

しかし今回の例のように七個も言語があると

models/article.rbは

scope :ja, -> {where(lang: :ja)}
scope :en, -> {where(lang: :en)}
scope :ar, -> {where(lang: :ar)}
scope :de, -> {where(lang: :de)}
scope :el, -> {where(lang: :el)}
scope :eo, -> {where(lang: :eo)}
scope :es, -> {where(lang: :es)}

と書かなくてはいけなくて結構邪魔になります。

もっと増えたらもっと邪魔になるわけでこれをもっと短く書きたい!

#class_evalを使ってみた

とりあえずclass_evalを使ってArticleのモデルにscopeを定義してみます。

使い方はこんな感じになりました。

Article.class_eval { scope ja, -> {where(lang: ja)}

これでscopeの設定ができるので後は配列を作ってループしたら出来上がり。

Lang = [ja, en, ar, de, el, eo, es, fr]

Lang.each do |l|
  Article.classs_eval { scope l, -> {where(lang: l)}
end 

これでOK

#もう少しいじってみる

もう少しいじってみることにして言語のファイルがconfig/localesにあるのですがそのファイルを見てscopeを定義してみたいと思います。

どういうことかというと

例えばconfig/localesに

en.yml
ja.yml
en.yml

というファイルがあったらそれを見てen,ja,enというスコープを作るということです。

config/localesのファイル名を取得するために

Dir.chdir("/mnt/c/users/owner/desktop/app_name/config/locales")
lang = Dir.glob("*").map {|l| l.match(/../)[0] }

こうすればconfig/localesのファイル名が取得できます。

これでconfig/localesにある言語化ファイルがある言語のスコープを作成できました

完成全体像はこちらです。


class Article < ApplicationRecord
    enum lang: {ja: 0, en: 1, ar: 2, de: 3,el: 4, eo: 5, es: 6, fr: 7}
end




Dir.chdir("/mnt/c/users/owner/desktop/latest_news/config/locales")
lang = Dir.glob("*").map {|l| l.match(/../)[0] }

lang.each do |l|
    Article.class_eval { scope l, -> {where(lang: l)}}
end 

逆にわかりにくいですね(笑)

おわり

メリークリスマス:snowman:

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?