在Rails中创建模型关系的问题

时间:2017-08-17 00:27:05

标签: ruby-on-rails ruby database model

我的程序中有3个主要模型;用户,国家,城市。

  • 用户和国家/地区有多对多的关系,我加入了这种关系 旅行模式。

  • 用户和城市有多对多的关系,我加入了 访问模型。

  • 国家和城市有一对多的关系。

当我运行rails db:migrate时,我没有出现任何错误并且一切都很好,但是当我尝试播种数据或进入控制台创建城市时,它将无法保存。将成功创建任何用户或国家,并且我能够在它们之间建立关系。

请参阅下面的模型。

user.rb

class User < ApplicationRecord

    before_save { self.email = email.downcase }
    #attr_accessible :user_name, :email
    validates_confirmation_of :password
    has_secure_password

    validates :user_name, presence: true, length: { maximum: 25 }
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
    validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX }
    validates :password, presence: true, confirmation: true, length: { minimum: 6 }
    validates :password_confirmation, presence: true

    has_many :trips
    has_many :visits
    has_many :countries, through: :trips
    has_many :cities, through: :visits


end

city.rb

class City < ApplicationRecord

    has_many :visits
    has_many :users, through: :visits
    belongs_to :country

end

country.rb

class Country < ApplicationRecord

  has_many :trips
  has_many :cities
  has_many :users, through: :trips

end

trip.rb

class Trip < ApplicationRecord

    belongs_to :country
    belongs_to :user

end

visit.rb

class Visit < ApplicationRecord

    belongs_to :city
    belongs_to :user

end

最初我甚至没有访问模型,我刚刚通过Trip模型加入了多对多关系。但是,在尝试解决问题时我把它分开了。

对此问题的任何帮助将不胜感激。如果您需要更多信息,请告诉我。

2 个答案:

答案 0 :(得分:1)

我首先要正确建模:

class City < ApplicationRecord
  has_many :visits
  has_many :users, through: :visits
  belongs_to :country
end

class Country < ApplicationRecord
  has_many :trips
  has_many :cities
  has_many :users, through: :trips 
end

class Trip < ApplicationRecord
  belongs_to :country
  belongs_to :user
  has_many :visits
  has_many :cities, through: :visits
end

class Visit < ApplicationRecord
  belongs_to :trip
  belongs_to :city
  has_one :country, through: :city
  has_one :user, through: :trip
end

# added
class User < ApplicationRecord
  # ...
  has_many :trips
  has_many :visits, through: :trips
  has_many :countries, through: :trips
  has_many :cities, through: :visits
end

这会在Trip和Visit之间创建一对多关联,并避免在两者上复制user_id外键。

在Rails 5中,一个主要的变化是默认情况下belongs_to关联是非可选的。

因此,如果您尝试创建没有国家/地区的城市,则验证将失败。但是,如果您从现有记录创建城市:

Country.first.cities.create!(name: 'Toronto')

或传递记录:

City.create!(name: 'Toronto', country: Country.first)

验证将通过。

您还可以将关联设置为可选,这是Rails 4中的行为:

class City < ApplicationRecord
  has_many :visits
  has_many :users, through: :visits
  belongs_to :country, optional: true
end

答案 1 :(得分:0)

由于城市有很多用户通过访问,那么你必须申报has_many:以下城市模型内的访问是示例代码可能可以帮助你解决问题

class City < ApplicationRecord
    has_many :visits
    has_many :users, through: :visits
    belongs_to :country
end

在您的控制台中创建城市时,请确保您在belongs_to国家/地区提供country_id,以下是示例代码:

@city = City.new
@city.country = Country.first
# @city.name = .... # your seed code 
@city.save