Working on sti branch will target to 0.3 version which will not compatible with 0.1 and 0.2
There are always some static data(not static page) in application.For example product type or student diploma type.
This gem can map these static data to a Dictionary#method like Dictionary#student_diploma_kind and generate a list of instance method on Student like @student.named_city which return city name (with locale if you need).
Branch sti is used to target version 0.3 which will totall rewrite. The main change is use STI to replace dict_types.
Version 0.2 support Rails4
Version 0.1 support Rails3.1
gem 'rails_dictionary'
or
gem "rails_dictionary", :git => 'git://github.com/raykin/rails_dictionary'
!!For users who update from old version to 0.0.9.1 or higher,Please run following command on app root after updates.
rails runner "DictType.new.delete_all_caches"
and in production
rails runner "DictType.new.delete_all_caches" -e production
or if you use file cache,just run
rake tmp:clear
See change log for brief info.
Run following task will give you a simple start.Maybe you should try it in a new application first.
rake dicts:generate rake dicts:sample_slave rake db:migrate rake dicts:sample_data
These task are just generate table dictionaries,dict_types,students and some sample data.The data should be
irb(main):013:0> DictType.select("id,name").all DictType Load (0.4ms) SELECT id,name FROM `dict_types` +----+----------------+ | id | name | +----+----------------+ | 1 | student_city | | 2 | student_school | +----+----------------+ 2 rows in set irb(main):014:0> Dictionary.select("id,name_en,name_zh,name_fr,dict_type_id").all Dictionary Load (1.2ms) SELECT id,name_en,name_zh,name_fr,dict_type_id FROM `dictionaries` +----+----------+---------+----------+--------------+ | id | name_en | name_zh | name_fr | dict_type_id | +----+----------+---------+----------+--------------+ | 3 | shanghai | 上海 | shanghai | 1 | | 4 | beijing | 北京 | Pékin | 1 | +----+----------+---------+----------+--------------+ 2 rows in set irb(main):016:0> Student.select("id,email,city,school").all Student Load (0.4ms) SELECT id,email,city,school FROM `students` +----+-------------------+------+--------+ | id | email | city | school | +----+-------------------+------+--------+ | 1 | [email protected] | 4 | | | 2 | [email protected] | 3 | | +----+-------------------+------+--------+ 2 rows in set
There is one convention on DictType.name .All value of DictType.name is “model_method” : student is model and city is method of student model.
Make sure you have two tables which named as dict_types and dictionaries.
Table dictionaries has one convention of naming column : name_locale.So the name_fr means this column have a french value,you can see more usage later. The students table is not required and variable by your application.
Here is what should be like.Student model can be other models.
class DictType < ActiveRecord::Base acts_as_dict_type end class Dictionary < ActiveRecord::Base acts_as_dictionary end class Student < ActiveRecord::Base # use acts_as_dict_slave when your rails_dictionary version < 0.2 acts_as_dict_consumer end
DictType.all_cached #=> return cache of DictType.all DictType.all_types = [:student_city,:student_school] # also cached Dictionary.student_city #=> [Dictionary.find(5),Dictionary.find(6)]
student_city is a dynamic method(from method missing) which returns a list of dictionary object which dict_type is “student_city”. Actually Dictionary will have as many dynamic methods as DictType.count and each dynamic method name is DictType.name. And student_city return an array,not ActiveRelation.So
Dictionary.student_school = [] Dictionary.student_city :locale => :en #=> [["beijing", 2],["shanghai",1]]
If you need a ActiveRelation, try scoped_student_city like
Dictionary.scoped_student_city.where(...)
You can use it in form select method like
collection_select :student,:city,Dictionary.student_city,:id,:name_en select :student,:city,Dictionary.student_city(params)
If params contains :locale => :fr,it returns a list of french name of student city (from name_fr in Dictioanry)
Student.find(1).named_city = "beijing" # when default locale is :en
Here is an other solution for international translation.
Student.find(1).named_city(:zh) = "北京" Student.find(1).named_city(:fr) = "Pékin" Student.find(1).named_city(:en) = "beijing"
Make sure your locale is en,not en-US.
Student has two belongs_to assocition which named as city_dict and school_dict,the naming convention is method_dict.
Student.find(1).city_dict #=> Dictionary.find(6)
Static data need orders frequently,so Dictionary.student_city :locale => :en has a default sort rules. By default,if the options contains locale,the results are sorted by the name value. If locale is :zh,sort rule is order by GBK encoding. Other locales are just order by alphabetical without case sensitive. You can override Dictionary.sort_dicts to customize your sort rule.But it is not recommended now as the code of sort design maybe change in a few month.
If you start a new application and there are more than 10 kinds of static data,you may have a try with the gem. However,if you see many static data in an old system and want to refactor it,the decision would be judged by the real situations.
The most used debug method would be DictType.all_types and Dictionary.student_city(or other dynamic generate method) When you get some confused with the output of these method,try running
rails tmp:clear
cause these methods all return static data(may be a mass of data),I just caches these output for better performance.If you change db data in db console(not through Rails) like running
delete from dict_types;
The rails cache would not refresh. In short,when you confused with the debug data,try running “rails tmp:clear” first.
Remove engine. Becase for the view layer we can use gem rails_admin. so this gem did not need rails engine. Is there any exist low level method to monitor the change of descendents? Add test code for cache DictType.tab_and_column,then uncomment the cache code.
There are no conventions and implemention to map Class like Ckeditor::Asset to a legal method name.