Ruby on Rails : 전역 상수를 정의 할 위치는?
첫 번째 Ruby on Rails webapp을 시작했습니다. 다양한 모델, 뷰, 컨트롤러 등이 있습니다.
전체 응용 프로그램에 적용되는 진정한 글로벌 상수의 정의를 고수 할 수있는 좋은 장소를 찾고 싶습니다. 특히, 그들은 내 모델의 논리와 내 견해에서 내린 결정 모두에 적용됩니다. 이 정의를 모든 모델과 모든 뷰에서 사용할 수있는 곳에 DRY 장소를 찾을 수 없습니다 .
구체적인 예를 들어, 상수를 원합니다 COLOURS = ['white', 'blue', 'black', 'red', 'green']
. 이것은 모델과 뷰 모두에서 모든 곳에서 사용됩니다. 한 곳에서 액세스 할 수 있도록 어디에서 정의 할 수 있습니까?
내가 시도한 것 :
- 그들은 대부분 같은과 관련있는 것을 model.rb 파일 정수 클래스 변수
@@COLOURS = [...]
. 그러나 나는 그것을 정의하는 깔끔한 방법을 찾지 못하여Card.COLOURS
과감한 것보다는 내 견해를 쓸 수Card.first.COLOURS
있었습니다. def colours ['white',...] end
같은 문제 와 같은 모델의 방법 .- application_helper.rb의 메소드-지금까지 내가하고있는 일이지만 도우미는 모델이 아닌보기에서만 액세스 할 수 있습니다
- application.rb 또는 environment.rb에서 무언가를 시도했을 수도 있지만 실제로는 올바르지 않습니다 (그리고 작동하지 않는 것 같습니다)
모델과 뷰에서 액세스 할 수있는 항목을 정의 할 방법이 없습니까? 내 말은, 모델과 뷰가 분리되어야한다는 것을 알고 있지만, 어떤 도메인에서는 반드시 동일한 도메인 별 지식을 참조해야하는 경우가 있습니까?
상수에 대해 모델이 실제로 "책임"인 경우에는 거기에 고정시켜야합니다. 새 객체 인스턴스를 만들지 않고 클래스 메서드를 만들어 액세스 할 수 있습니다.
class Card < ActiveRecord::Base
def self.colours
['white', 'blue']
end
end
# accessible like this
Card.colours
또는 클래스 변수와 접근자를 만들 수 있습니다. 그러나 클래스 변수가 상속 및 멀티 스레드 환경에서 놀라운 역할을 할 수 있으므로 권장하지 않습니다.
class Card < ActiveRecord::Base
@@colours = ['white', 'blue']
cattr_reader :colours
end
# accessible the same as above
위의 두 옵션을 사용하면 필요한 경우 접근 자 메서드를 호출 할 때마다 반환 된 배열을 변경할 수 있습니다. 진정으로 변경 불가능한 상수가있는 경우 모델 클래스에서 정의 할 수도 있습니다.
class Card < ActiveRecord::Base
COLOURS = ['white', 'blue'].freeze
end
# accessible as
Card::COLOURS
다음 예제와 같이 초기화 프로그램의 모든 곳에서 액세스 할 수있는 전역 상수를 만들 수도 있습니다. 색상이 실제로 전체적이며 둘 이상의 모델 컨텍스트에서 사용되는 경우이 위치가 가장 적합합니다.
# put this into config/initializers/my_constants.rb
COLOURS = ['white', 'blue'].freeze
참고 : 상수를 위에서 정의 할 때 종종 freeze
배열을 원합니다 . 그러면 다른 요소가 나중에 실수로 새 요소를 추가하여 배열을 수정하는 것을 방지 할 수 있습니다. 개체가 고정되면 더 이상 변경할 수 없습니다.
일부 옵션 :
상수 사용하기 :
class Card
COLOURS = ['white', 'blue', 'black', 'red', 'green', 'yellow'].freeze
end
클래스 인스턴스 변수를 사용하여 지연로드 됨 :
class Card
def self.colours
@colours ||= ['white', 'blue', 'black', 'red', 'green', 'yellow'].freeze
end
end
그것이 진정한 글로벌 상수라면 ( 그러나이 성격의 글로벌 상수를 피하십시오 ), config/initializers/my_constants.rb
예를 들어 최상위 상수를 넣는 것도 고려할 수 있습니다 .
Rails 4.2부터는 다음과 같은 config.x
속성을 사용할 수 있습니다 .
# config/application.rb (or config/custom.rb if you prefer)
config.x.colours.options = %w[white blue black red green]
config.x.colours.default = 'white'
다음과 같이 사용할 수 있습니다.
Rails.configuration.x.colours.options
# => ["white", "blue", "black", "red", "green"]
Rails.configuration.x.colours.default
# => "white"
Another method of loading custom config:
# config/colours.yml
default: &default
options:
- white
- blue
- black
- red
- green
default: white
development:
*default
production:
*default
# config/application.rb
config.colours = config_for(:colours)
Rails.configuration.colours
# => {"options"=>["white", "blue", "black", "red", "green"], "default"=>"white"}
Rails.configuration.colours['default']
# => "white"
In Rails 5 & 6, you can use the configuration
object directly for custom configuration, in addition to config.x
. However, it can only be used for non-nested configuration:
# config/application.rb
config.colours = %w[white blue black red green]
It will be available as:
Rails.configuration.colours
# => ["white", "blue", "black", "red", "green"]
If a constant is needed in more than one class, I put it in config/initializers/contant.rb always in all caps (list of states below is truncated).
STATES = ['AK', 'AL', ... 'WI', 'WV', 'WY']
They are available through out the application except in model code as such:
<%= form.label :states, %>
<%= form.select :states, STATES, {} %>
To use the constant in a model, use attr_accessor to make the constant available.
class Customer < ActiveRecord::Base
attr_accessor :STATES
validates :state, inclusion: {in: STATES, message: "-- choose a State from the drop down list."}
end
For application-wide settings and for global constants I recommend to use Settingslogic. This settings are stored in YML file and can be accessed from models, views and controllers. Furthermore, you can create different settings for all your environments:
# app/config/application.yml
defaults: &defaults
cool:
sweet: nested settings
neat_setting: 24
awesome_setting: <%= "Did you know 5 + 5 = #{5 + 5}?" %>
colors: "white blue black red green"
development:
<<: *defaults
neat_setting: 800
test:
<<: *defaults
production:
<<: *defaults
Somewhere in the view (I prefer helper methods for such kind of stuff) or in a model you can get, for ex., array of colors Settings.colors.split(/\s/)
. It's very flexible. And you don't need to invent a bike.
Use a class method:
def self.colours
['white', 'red', 'black']
end
Then Model.colours
will return that array. Alternatively, create an initializer and wrap the constants in a module to avoid namespace conflicts.
Another option, if you want to define your constants in one place:
module DSL
module Constants
MY_CONSTANT = 1
end
end
But still make them globally visible without having to access them in fully qualified way:
DSL::Constants::MY_CONSTANT # => 1
MY_CONSTANT # => NameError: uninitialized constant MY_CONSTANT
Object.instance_eval { include DSL::Constants }
MY_CONSTANT # => 1
A common place to put application-wide global constants is inside config/application
.
module MyApp
FOO ||= ENV.fetch('FOO', nil)
BAR ||= %w(one two three)
class Application < Rails::Application
config.foo_bar = :baz
end
end
I typically have a 'lookup' model/table in my rails program and use it for the constants. It is very useful if the constants are going to be different for different environments. In addition, if you have a plan to extend them, say you want to add 'yellow' on a later date, you could simply add a new row to the lookup table and be done with it.
If you give the admin permissions to modify this table, they will not come to you for maintenance. :) DRY.
Here is how my migration code looks like:
class CreateLookups < ActiveRecord::Migration
def change
create_table :lookups do |t|
t.string :group_key
t.string :lookup_key
t.string :lookup_value
t.timestamps
end
end
end
I use seeds.rb to pre-populate it.
Lookup.find_or_create_by_group_key_and_lookup_key_and_lookup_value!(group_key: 'development_COLORS', lookup_key: 'color1', lookup_value: 'red');
Try to keep all constant at one place, In my application I have created constants folder inside initializers as follows:
and I usually keep all constant in these files.
In your case you can create file under constants folder as colors_constant.rb
colors_constant.rb
Don't forgot to restart server
The global variable should be declare in config/initializers
directory
COLOURS = %w(white blue black red green)
According your condition, you can also define some environmental variables, and fetch it via ENV['some-var']
in ruby code, this solution may not fit for you, but I hope it may help others.
Example: you can create different files .development_env
, .production_env
, .test_env
and load it according your application environments, check this gen dotenv-rails which automate this for your.
참고URL : https://stackoverflow.com/questions/4110866/ruby-on-rails-where-to-define-global-constants
'Programing' 카테고리의 다른 글
파이썬 정수 나누기 수레 (0) | 2020.05.07 |
---|---|
Java 8 람다, Function.identity () 또는 t-> t (0) | 2020.05.07 |
Kotlin의 MutableList를 초기화하여 MutableList를 비우려면 어떻게해야합니까? (0) | 2020.05.07 |
UI 스레드에서 작업 계속 (0) | 2020.05.07 |
background-size와 같은 것이 있습니까? 이미지 요소에 대해 포함하고 포함합니까? (0) | 2020.05.07 |