我正在创建一个与Active Record紧密集成的Rails gem。 gem需要定义许多字段。例如:
class User < ActiveRecord::Base
# requires 'avatar_identifier', 'avatar_extension', 'avatar_size'
has_attached :avatar
end
是否可能有类似的内容:
rails g model user name:string avatar:attached
导致:
create_table :users do |t|
t.string :name
t.string :avatar_identifier
t.string :avatar_extension
t.integer :avatar_size
end
如果无法做到这一点,可以采取任何方式:
create_table :users do |t|
t.string :name
t.attached :avatar
end
生成多个字段?谢谢!
答案 0 :(得分:4)
其实如果你打电话
rails g model profile name:string next:attached
rails allready通过
生成迁移def self.up
create_table :profiles do |t|
t.string :name
t.attached :next
t.timestamps
end
end
但是您可以通过将其置于默认迁移模板中来覆盖它 /lib/templates/active_record/model/migration.rb
您应该编写一个rake my_gem:setup任务来将文件放在那里 我没有尝试过,但我认为rails不会在这些模板的非引擎宝石中搜索
您的迁移模板内容将如下所示
class <%= migration_class_name %> < ActiveRecord::Migration
def self.up
create_table :<%= table_name %> do |t|
<% for attribute in attributes -%>
<% if attribute.type.to_s == "attached" %>
t.string :<%= attribute.name %>_identifier
t.string :<%= attribute.name %>_extension
t.integer :<%= attribute.name %>_size
<% else %>
t.<%= attribute.type %> :<%= attribute.name %>
<% end %>
<% end -%>
<% if options[:timestamps] %>
t.timestamps
<% end -%>
end
end
def self.down
drop_table :<%= table_name %>
end
end
答案 1 :(得分:3)
虽然普拉文确实指出了正确的方向,但我发现实施它并不简单。我做了以下操作,我在config/initializers
中添加了一个文件(名称不相关),其中包含以下内容:
require 'active_support'
require 'active_record'
class YourApplication
module SchemaDefinitions
module ExtraMethod
def attachment(*args)
options = args.extract_options!
args.each do |col|
column("#{col}_identifier", :string, options)
column("#{col}_extension", :string, options)
column("#{col}_size", :integer, options)
end
end
end
def self.load!
::ActiveRecord::ConnectionAdapters::TableDefinition.class_eval { include YourApplication::SchemaDefinitions::ExtraMethod }
end
end
end
ActiveSupport.on_load :active_record do
YourApplication::SchemaDefinitions.load!
end
然后你可以做类似的事情:
rails g model Person name:string title:string avatar:attachment
将创建以下迁移:
def self.up
create_table :people do |t|
t.string :name
t.string :title
t.attachment :avatar
t.timestamps
end
end
如果您随后运行迁移rake db:migrate
,则会创建以下Person
模型:
ruby-1.9.2-p0 > Person
=> Person(id: integer, name: string, title: string, avatar_identifier: string, avatar_extension: string, avatar_size: integer, created_at: datetime, updated_at: datetime)
希望这会有所帮助!!
答案 2 :(得分:2)
我认为t.attached
与多态关联中的t.references
相似。
参考references
方法,您可以使用下面的内容
def attached(*args)
options = args.extract_options!
column(:avatar_identifier, :string, options)
column(:avatar_extension, :string, options)
column(:avatar_size, :integer, options)
end
您可能希望延长ActiveRecord::ConnectionAdapters::TableDefinition
看看这个
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#method-i-references