Soru ActiveRecord nesnesindeki niteliklerin türlerini alma


Program aracılığıyla (örn. Geçiş komut dosyasında ve veritabanında olduğu gibi) bilinen türlerin elde edilip edilmediğini bilmek istiyorum (veriyi orada bir yerde biliyorum).

Örneğin, tüm özellik adlarıyla başa çıkabilirim:

ar.attribute_names.each { |name| puts name }

.attributes, adların mevcut değerleriyle eşleştirilmesini döndürür (örneğin, alan ayarlanmamışsa tip bilgisi yok).

Tip bilgileriyle gördüğüm bazı yerler:

komut dosyasında / konsolda bir AR öğesinin adını yazın:

>> Driver
=> Driver(id: integer, name: string, created_at: datetime, updated_at: datetime)

Öyleyse açıkça türleri bilir. Ayrıca, bir attr adını alan ve bir sütun nesnesini döndüren - altta yatan veritabanı sütun nesnesinde gömülü olan bir tür olan .column_for_attribute var, ancak bunu elde etmek için temiz bir yol gibi görünmüyor.

Ayrıca yeni "ActiveModel" için uygun olan bir yol varsa (rails3) ve veritabanı özelliklerinden ayrıştırılırsa belki ilgilenirim (ama belki de bilgi bir parçanın parçası olmayacaktır). olup olmadığını öğrenin).

Teşekkürler.


58
2018-03-08 05:57


Menşei




Cevaplar:


Rails 3'te, modeliniz için "Sürücü" Driver.columns_hash.

Driver.columns_hash["name"].type  #returns :string

Onları tekrarlamak istiyorsanız, şöyle bir şey yaparsınız:

Driver.columns_hash.each {|k,v| puts "#{k} => #{v.type}"}

aşağıdaki çıktılar:

id => integer
name => string
created_at => datetime
updated_at => datetime

88
2018-03-27 18:49



Bir değer bir sütunla eşleşiyorsa nasıl test edebilirim, böyle bir şey 2.is_a? Driver.columns_hash["name"].type - mariowise
Hayır, bilmiyorum. - Grant Birchmeier
Bunun hala Rays 4.2'de çalıştığını doğrulayabilirim. - Phil


Bunu yaparak sütun türlerine erişebilirsiniz:

#script/console
Driver.columns.each {|c| puts c.type}

Belirli bir Modeldeki tüm sütun türlerinin bir listesini almak isterseniz, şunları yapabilirsiniz:

Driver.columns.map(&:type) #gets them all
Driver.columns.map(&:type).uniq #gets the unique ones

19
2018-03-08 06:14



Teşekkür ederim. Sanırım bu, ActiveModel'in bir parçası olmayacak olsa da, sütunlara bağlı olduğundan (muhtemelen AM'ye getirmeyecek). Ama bu sadece AR için harika çalışıyor. Biliyorsun aslında biliyordum ki aklımın gerisinde, ama bir sebepten dolayı bunu engelledi. - Michael Neale


Raylar 5'te, bunu Veritabanından bağımsız olarak yapabilirsiniz. (Ek) öznitelikleri tanımlamak için yeni Nitelikler API'sını kullanırsanız bu önemlidir.

Model sınıfından tüm özellikleri alma:

pry> User.attribute_names
=> ["id",
 "firstname",
 "lastname",
 "created_at",
 "updated_at",
 "email",...

Türünü almak:

pry> User.type_for_attribute('email')
=> #<ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlString:0x007ffbab107698
 @limit=255,
 @precision=nil,
 @scale=nil>

Bu bazen ihtiyaç duyulandan daha fazla bilgi. Tüm bu türleri bir çekirdek kümesine (: tam sayı,: dize vb.) Eşleyen bir kolaylık işlevi vardır.

> User.type_for_attribute('email').type
=> :string 

Ayrıca, tüm bu verileri, bir çağrıyla geri dönen 'name': type karması.


9
2018-02-24 02:59



Bu da Rails 4.2'de çalışıyor. Bunu not etmek önemlidir type_for_attribute('id') sadece bir dize alır. Biraz kafa karıştırıcı çünkü type_for_attribute('id').type bir sembol döndürür. - xander-miller
Veritabanından bağımsız olarak ORM'yi kastediyorsanız, Mongoid bunu uygulamamıştır. type_for_attribute Henüz. Belki de Rails 5'in resmi bir sürümü var. - Cyril Duchon-Doris


Raylarda 5 bu, veri alanlarıyla birlikte tüm alan adlarının bir listesini verecektir:

Model_Name.attribute_names.each do |k| puts "#{k} = #{Model_Name.type_for_attribute(k).type}" end

3
2017-12-12 13:36



Not type_for_attribute dizeleri bekliyor. Mutlu bir şekilde semboller veya varolmayan isimler alır, bir ActiveModel :: Type :: Value değerini döndürmez! IMO bir hata, rapor etmeye / düzeltmeye çalışacağım. - Beni Cherniavsky-Paskin


Bu snippet, bir modelin tüm özelliklerini bir karmada ilişkili veritabanı veri türleriyle birlikte verecektir. Sadece Post'u Aktif Kayıt Modelinizle değiştirin.

Post.attribute_names.map {|n| [n.to_sym,Post.type_for_attribute(n).type]}.to_h

Böyle bir hashta geri dönecek.

=> {:id=>:integer, :title=>:string, :body=>:text, :created_at=>:datetime, :updated_at=>:datetime, :topic_id=>:integer, :user_id=>:integer} 

1
2018-02-25 18:43