tutorial sirve rails que para modelos español ejemplos caracteristicas aprender ruby-on-rails jruby migration activerecord-jdbc

ruby-on-rails - sirve - ruby on rails modelos



Problema de creación del esquema de Rails (6)

Estoy usando Jruby y Rails 2.2.2. Mi problema es que tengo una migración que no se está escribiendo correctamente en el esquema de la base de datos.

Aquí está mi migración:

class CreateNotes < ActiveRecord::Migration def self.up create_table(:notes, :options => ''ENGINE=MyISAM'') do |t| t.string :title t.text :body t.timestamps end execute "alter table notes ADD FULLTEXT(title, body)" end

Esto es lo que produce en schema.rb

create_table "notes", :force => true do |t| t.string "title" t.text "body" t.datetime "created_at" t.datetime "updated_at" end add_index "notes", ["title", "body"], :name => "title"

Tengo dos preguntas:

  • ¿Cómo obtengo ''ENGINE=MyISAM'' en el esquema?
  • ¿Por qué mi sentencia de ejecución se convirtió en add_index "notes", ["title", "body"], :name => "title" ? y ¿cómo obligo a las migraciones a dejarlo como una instrucción de ejecución?

Gracias a Christian Lescuyer por la respuesta. Sin embargo, cuando probé esto, nada cambió. Descomenté la línea config.active_record ... pero mi esquema no ha cambiado. He intentado esto en jruby y en ruby ​​1.8.6 con rieles 2.2.2 y rieles laterales y no hay cambios en el esquema. ¿Alguien puede decirme qué estoy haciendo mal?


Como utilizo restricciones de clave externa, utilizo el formato SQL para migraciones. En environment.rb :

# Use SQL instead of Active Record''s schema dumper when creating the test database. # This is necessary if your schema can''t be completely dumped by the schema dumper, # like if you have constraints or database-specific column types config.active_record.schema_format = :sql


Christian tiene razón

hacer

config.active_record.schema_format =: sql

en environment.rb

pero luego debe usar un formato de volcado de esquema y una ubicación de archivo diferentes. intente hacer su migración y busque "schema.sql" en lugar de scehema.rb

El motivo de todo esto es que el punto del archivo de esquema es una base de datos no específica (funciona para todos los tipos de bases de datos). por lo tanto, cuando utiliza funciones que solo funcionan en mysql a través de una sentencia de ejecución no agrupada, no pueden ser calzados en schema.rb


Yo también esperaba ver un nuevo archivo .sql después de un "rake db: migrate", una vez que configuré

config.active_record.schema_format = :sql

en config / environment.rb.

Aparentemente, no es así como funciona, sin embargo. Debo hacer esto explícitamente para obtener un archivo db / [development | test | production] _structure.sql:

rake db:structure:dump


Para utilizar la variante SQL para probar (en lugar de schema.rb), deberá usar

rake db: test: clone_structure

Nuestro esquema usa UUID (uuid gem) y también el agradable FK plug-in de Red Hill on Rails (RHoR). Desafortunadamente, los FK requieren PK que solo se pueden agregar usando EJECUCIONES en las migraciones.

Es bien sabido que estos ejecutables no llegan a schema.rb; sin embargo, fue más difícil encontrar la alternativa de rake a db: test: prepararse para aplicaciones que no pueden usar schema.rb.


Solo una actualización para aquellos en Rails 3 (beta 4, actualmente) - La solución de Christian sigue siendo correcta, solo el lugar correcto para poner la línea es en config/application.rb , bajo el alcance de la clase Application , que debe definirse en una módulo nombrado después de su proyecto Rails.


El siguiente monkeypatch resuelve tanto el problema del índice FULLTEXT como la opción del motor de DB para su descargador de esquemas (Rails 3.2). Puedes ponerlo en config/initializers/ (ej. schema_dumper_monkeypatch.rb ):

module ActiveRecord class SchemaDumper def table(table, stream) columns = @connection.columns(table) begin tbl = StringIO.new # first dump primary key column if @connection.respond_to?(:pk_and_sequence_for) pk, _ = @connection.pk_and_sequence_for(table) elsif @connection.respond_to?(:primary_key) pk = @connection.primary_key(table) end tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}" if columns.detect { |c| c.name == pk } if pk != ''id'' tbl.print %Q(, :primary_key => "#{pk}") end else tbl.print ", :id => false" end tbl.print ", :force => true" # Add table engine res = @connection.execute "SHOW TABLE STATUS LIKE ''#{table}''" engine = res.first[res.fields.index("Engine")] rescue nil tbl.print ", :options => ''ENGINE=#{engine}''" if engine res = nil # Free the result tbl.puts " do |t|" # then dump all non-primary key columns column_specs = columns.map do |column| raise StandardError, "Unknown type ''#{column.sql_type}'' for column ''#{column.name}''" if @types[column.type].nil? next if column.name == pk spec = {} spec[:name] = column.name.inspect # AR has an optimization which handles zero-scale decimals as integers. This # code ensures that the dumper still dumps the column as a decimal. spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) } ''decimal'' else column.type.to_s end spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && spec[:type] != ''decimal'' spec[:precision] = column.precision.inspect if column.precision spec[:scale] = column.scale.inspect if column.scale spec[:null] = ''false'' unless column.null spec[:default] = default_string(column.default) if column.has_default? (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")} spec end.compact # find all migration keys used in this table keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map{ |k| k.keys }.flatten # figure out the lengths for each column based on above keys lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max } # the string we''re going to sprintf our values against, with standardized column widths format_string = lengths.map{ |len| "%-#{len}s" } # find the max length for the ''type'' column, which is special type_length = column_specs.map{ |column| column[:type].length }.max # add column type definition to our format string format_string.unshift " t.%-#{type_length}s " format_string *= '''' column_specs.each do |colspec| values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len } values.unshift colspec[:type] tbl.print((format_string % values).gsub(/,/s*$/, '''')) tbl.puts end tbl.puts " end" tbl.puts indexes(table, tbl) tbl.rewind stream.print tbl.read rescue => e stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}" stream.puts "# #{e.message}" stream.puts end stream end def indexes(table, stream) if (indexes = @connection.indexes(table)).any? add_index_statements = indexes.map do |index| if index.name =~ /fulltext/i " execute /"CREATE FULLTEXT INDEX #{index.name} ON #{index.table} (#{index.columns.join('','')})/"" elsif index.name =~ /spatial/i " execute /"CREATE SPATIAL INDEX #{index.name} ON #{index.table} (#{index.columns.join('','')})/"" else statement_parts = [ (''add_index '' + remove_prefix_and_suffix(index.table).inspect), index.columns.inspect, ('':name => '' + index.name.inspect), ] statement_parts << '':unique => true'' if index.unique index_lengths = (index.lengths || []).compact statement_parts << ('':length => '' + Hash[index.columns.zip(index.lengths)].inspect) unless index_lengths.empty? index_orders = (index.orders || {}) statement_parts << ('':order => '' + index.orders.inspect) unless index_orders.empty? '' '' + statement_parts.join('', '') end end stream.puts add_index_statements.sort.join("/n") stream.puts end end end end