如果我使用DataMapper的“has n”和“belongs_to”方法,为什么我的一个表没有被填充?

时间:2012-11-10 01:53:21

标签: ruby sqlite associations datamapper belongs-to

我现在正在处理sqlite3上的DataMapper。我必须定义创建两个表的模型:“公司”和“应用程序”。

每个应用程序属于一个公司,每个公司都有很多应用程序。我想在我的模型中表示这种关系,但是我为每个类添加了“has n”和“belongs_to”方法,当在一堆应用程序上调用#create时,App类停止工作,它们不会插入到数据库中。 / p>

如果我没有关联方法,那么一切正常。

这是我的DataMapper代码:

DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/app.db")

class Company
    include DataMapper::Resource

    property :id, Serial
    property :company_name,
    property :company_id, Text, :unique => true

    has n, :apps
end

class App
    include DataMapper::Resource

    property :id, Serial
    property :app_id, Integer
    property :bundle_id, Text
    property :game_name, Text
    property :company_name, Text
    property :created_at, DateTime
    property :rank, Integer

    belongs_to :company
end

DataMapper.finalize.auto_upgrade!

puts 'Database and tables created'

这是我用来填充表格的代码

companies_in_chart.each do |company|
    @add_company = Company.create(
        :company_name   => company["company_name"],
        :company_id     => company["company_id"]
    )
end
puts "Inserted companies into database"

apps_arr.each do |app|
    @new_app = App.create(
        :app_id         => app["app_id"],
        :bundle_id      => app["bundle_id"],
        :game_name      => app["game_name"],
        :company_name   => app["company_name"],
        :created_at     => app["DateTime"],
        :rank           => app["rank"]
    )
end
puts "Inserted apps into database"

编辑:新代码

#Set up database and apps table
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/app.db")

class Company
    include DataMapper::Resource

    property :id, Serial
    property :company_name, Text,    :required => true, :lazy => false
    property :company_id, Text,      :required => true, :lazy => false, :unique => true

    has n, :apps
end

class App
    include DataMapper::Resource

    property :id, Serial
    property :app_id, Integer,      :required => true
    property :bundle_id, Text,      :required => true, :lazy => false
    property :game_name, Text,      :required => true, :lazy => false
    property :company_id, Text,     :required => true, :lazy => false
    property :created_at, DateTime
    property :rank, Integer

    belongs_to :company
end

DataMapper.finalize.auto_upgrade!

puts 'Database and tables created'

#Insert apps and companies into database
apps_arr.each do |app|

    # Creates a new company based on app entry if the company does
    # not exist in the companies table
    @add_company = Company.create(
        :company_name   => app["company_name"],
        :company_id     => app["company_id"]
    )

    @add_app = App.create(
        :app_id         => app["app_id"],
        :bundle_id      => app["bundle_id"],
        :game_name      => app["game_name"],
        :company_id     => app["company_id"],
        :created_at     => app["DateTime"],
        :rank           => app["rank"]
    )
end
puts "Inserted app and companies into database"

@company = Company.first
ap @company # => #<Company @id=1 @company_name="Rovio Entertainment Ltd" @company_id="rovio">

ap @company.apps # => [] --I was hoping it would return all of Rovio's apps in the database

1 个答案:

答案 0 :(得分:3)

未创建的应用导致您在创建应用时必须附加公司。

如果您要添加未附加到任何公司的应用,请在App模型中使用:

belongs_to :company, :required => false

在创建应用时附加公司:

#Insert apps and companies into database

apps_arr.each do |app|

  # Creates a new company based on app entry if the company does
  # not exist in the companies table

  company = Company.first_or_create(
    :company_name   => app["company_name"],
    :company_id     => app["company_id"]
  )

  app = App.first_or_create(
    :company        => company, # you missed this
    :app_id         => app["app_id"],
    :bundle_id      => app["bundle_id"],
    :game_name      => app["game_name"],
    :company_id     => app["company_id"],
    :created_at     => app["DateTime"],
    :rank           => app["rank"]
  )
end
puts "Inserted app and companies into database"

我成功地在CIBox上复制了你的代码,它运行得很好。

请参阅the code and live demo here

如您所见,它创建了一家公司并将其附加到创建的应用程序。

Company.first.apps返回已创建的应用,因此关联正常工作。