【问题标题】:Keep getting syntax error when "rake db:migrate"“rake db:migrate”时不断出现语法错误
【发布时间】:2019-01-19 11:46:57
【问题描述】:

我的代码:

class Song < ActiveRecord::Base
   belongs_to :artist
   has_many :song_genres
   has_many :genres, :through :song_genres
end

错误:

rake aborted!
SyntaxError: .../app/models/song.rb:4: syntax error, unexpected ':', expecting keyword_end
has_many :genres, :through :song_genres

当我使用“=>”时:

class Song < ActiveRecord::Base
  belongs_to :artist
  has_many :song_genres
  has_many :genres, :through => :song_genres
end

我不再收到错误消息,但现在我在一次迁移中收到另一条类似情况的错误消息。

rake aborted!
SyntaxError: .../db/migrate/01_create_artists_table.rb:4: syntax error, unexpected tSYMBEG, expecting keyword_end
                t.string :name

那里的代码如下所示:

class CreateArtistsTable < ActiveRecord::Migration
  def change
        create_table :artists |t|
        t.string :name
        t.has_many :songs 
        t.has_many :genres, through: :song_genres 
        end 
  end
end

我是新手,非常感谢您的帮助!谢谢! :)

【问题讨论】:

    标签: ruby activerecord migration syntax-error rake


    【解决方案1】:

    create_table :artists |t| 应该是create_table :artists do |t|

    此外,以下 2 行不应包含在 artists 迁移中。他们错了。这不是在 Rails 中创建了多少直通关系。它们应该是模型的一部分,而不是迁移。

    t.has_many :songs 
    t.has_many :genres, through: :song_genres
    

    Song模型里面,写成这样。

    has_many :genres, through: :song_genres
    

    song_genres 表创建一个迁移,以设置具有许多虽然关系。

    create_table :song_genres do |t|
      t.belongs_to :songs
      t.belongs_to :genres
    end
    

    【讨论】:

    • 我对您的答案投了反对票,因为我认为通过发布简短答案并一遍又一遍地编辑它来尝试首先进入对其他回答者是不公平的。我看到了你的第一次迭代,它非常不完整,因此我拒绝投票。
    • @thesecretmaster 我这样回答。欢迎您投反对票!我们不是在比赛中。
    【解决方案2】:

    为您的第一条错误消息尝试以下语法:

    has_many :genres, through: :song_genres

    【讨论】:

      【解决方案3】:

      这里有两个问题。在您的模型中,您的关键字参数的语法错误。在 ruby​​ 中,您可以通过在关键字之后和值之前放置冒号来将参数作为关键字传递,例如key: :value 而不是:key :value。单词前的冒号声明一个符号,这不是您在这里所做的。所以,你的模型实际上应该是这样的:

      class Song < ActiveRecord::Base
         belongs_to :artist
         has_many :song_genres
         # has_many :genres, :through :song_genres
         has_many :genres, through: :song_genres
         # Which is shorthand for `has_many :genres, :through => :song_genres`
      end
      

      而且,在您的迁移中,您不能指定 through。那是只存在于您的模型中的东西。您还弄错了迁移的语法。它应该看起来更像这样:

      create_table :table_name do |t|
        t.type :column_name
      end
      

      当您说t.has_many 时,您是在要求 ActiveRecord 创建一个类型为“has_many”的列,该类型不是有效类型。相反,您需要stringintegerdatetime 等。对于另一个表的引用,您可以使用t.references。因此,您的迁移应该看起来更像这样:

      class CreateArtistsTable < ActiveRecord::Migration
        def change
              create_table :artists |t|
              t.string :name
              t.<type> :songs 
              t.<type> :genres #, through: :song_genres 
              end 
        end
      end
      

      具体来说,考虑到您要创建的关系,它会更像这样:

      class CreateArtistsTable < ActiveRecord::Migration
        def change
          create_table :artists |t|
            t.string :name
          end 
          add_reference :songs, :artist
          create_table :song_genres do |t|
            t.references :song
            t.references :genre
          end
        end
      end
      

      附带说明,在 ruby​​ 中,您应该使用 2 个空格进行缩进。

      【讨论】:

      • t.&lt;type&gt; :genres, through: :song_genres 可能在迁移中吗?我从未见过或使用过它。
      • 不,不是,我只是想在纠正其余错误之前纠正t.has_many
      • CreateArtistsTable 迁移不应创建 2 个不同的表。它有效,但语义错误。
      • 一次迁移创建 2 个表绝对没有错。事实上,对于多对多关系,这通常是最好的方法。
      • 不,不是。您的回答具有误导性。它们有效,但这不是您建议其他人这样做的方式。为它们创建单独的迁移。
      猜你喜欢
      • 2013-11-28
      • 1970-01-01
      • 2012-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-06
      • 2018-02-05
      • 2012-11-23
      相关资源
      最近更新 更多