在Rails中,“执行<<-SQL”是什么意思?

nia*_*ian 5 ruby syntax ruby-on-rails heredoc

当我在http://guides.rubyonrails.org/active_record_migrations.html中在线引用active_record_migrations时

在以下代码段中:

class ExampleMigration < ActiveRecord::Migration[5.0]
  def up
    create_table :distributors do |t|
      t.string :zipcode
    end

    # add a CHECK constraint
    execute <<-SQL
      ALTER TABLE distributors
        ADD CONSTRAINT zipchk
        CHECK (char_length(zipcode) = 5);
    SQL

    add_column :users, :home_page_url, :string
    rename_column :users, :email, :email_address
  end

  def down
    rename_column :users, :email_address, :email
    remove_column :users, :home_page_url

    execute <<-SQL
      ALTER TABLE distributors
        DROP CONSTRAINT zipchk
    SQL

    drop_table :distributors
  end
end
Run Code Online (Sandbox Code Playgroud)

以下陈述是什么意思?

execute <<-SQL
  ALTER TABLE distributors
    ADD CONSTRAINT zipchk
    CHECK (char_length(zipcode) = 5);
SQL
Run Code Online (Sandbox Code Playgroud)

使用运行此迁移rails db:migrate,出现错误:

SQLite3::SQLException: near "CONSTRAINT": syntax error:           ALTER TABLE distributors
            ADD CONSTRAINT zipchk
              CHECK (char_length(zipcode) = 5) NO INHERIT;
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅3.9使用可逆

And*_*eko 8

它称为heredoc,与迁移,SQL或其他任何特定内容无关:

如果要编写大量文本,则可以使用“此处文档”或“ heredoc”:

expected_result = <<HEREDOC

This would contain specially formatted text.

That might span many lines
HEREDOC
Run Code Online (Sandbox Code Playgroud)

此处的文档从<< << HEREDOC之后的行开始,并以HEREDOC开头的下一行结束。结果包括结尾的换行符。

您可以在Heredoc中使用任何标识符,但是通常使用全大写的标识符。

如果在<<后面加上“-”,则可以缩进结尾的标识符:

  expected_result = <<-INDENTED_HEREDOC
This would contain specially formatted text.

That might span many lines
  INDENTED_HEREDOC
Run Code Online (Sandbox Code Playgroud)

请注意,虽然可以将结束标识符缩进,但始终将内容视为左对齐。如果缩进内容,则这些空格将出现在输出中。

由于ActiveRecord :: ConnectionAdapters :: DatabaseStatements#execute将字符串作为参数,因此您正在传递此字符串,格式正确。


Aja*_*jay 0

此语法用于以 sql 方式创建迁移,而不是遵循 Rails 活动记录方式。

好处:它提供了对 SQL 操作的更多控制,添加索引、约束等。

句法:

execute <<-EOSQL your_sql_here EOSQL

class CreateEmployers < ActiveRecord::Migration def up execute <<-EOSQL CREATE TABLE employers ( id bigint(20) NOT NULL AUTO_INCREMENT, designation_id int(11) NOT NULL, salary int(11) DEFAULT NULL); EOSQL end def down execute <<-EOSQL DROP TABLE employers; EOSQL end end