2017-08-17 93 views
0

我在我的程序中有3个主要模型;用户,国家,城市。在Rails中创建模型关系的问题

  • 用户和乡村有许多一对多的关系,我与 跳闸模式加入。

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

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

当我运行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+\-.][email protected][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 

我本来甚至没有访问模型,我只是过跳闸模型都加入许多一对多的关系。但是,在试图解决这个问题时,我将它分开了。

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

+0

你确定你有所有模型的迁移? db:如果无事可做,迁移将成功返回。当你试图保存时,你会得到什么样的信息? (尝试使用保存!而不是从控制台保存,如果它只是返回false)。 – cpm

+0

我得到'ActiveRecord :: RecordInvalid:验证失败:国家必须存在',当一个保存!我有国家,我尝试了一些像'Country.find(1).cities << [City.create(name:“Toronto”)]'',希望在创建该城市时将该城市分配给该国家将有所帮助,但不会运气。 –

+0

你用country_id保存城市吗? – hashrocket

回答

0

通过参观城市的has_many用户,那么你必须声明的has_many:城市模型内部访问下面的示例代码也许可以帮助你的问题

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

当您在控制台中创建的城市,要确保你给COUNTRY_ID在belongs_to的国家,这里是一个示例代码:

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

谢谢,我已经添加,以及到用户模型,但我仍然有同样的问题。 我编辑了上面的代码以添加更改。 –

+0

好吧,我刚刚编辑了我的答案 – widjajayd

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) 

验证将通过。

您还可以设置关联作为可选这是在轨道4,5的行为:

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

但是我做了你所建议的改变,但是当我尝试创建一个城市时,它仍然不起作用。我得到错误 - 'ActiveModel :: UnknownAttributeError:城市'的未知属性'country_id'。我的用户模型是否正确设置? –

+0

'ActiveModel :: UnknownAttributeError'意味着你还没有创建'country_id'列。如果您创建了这样的迁移,您可能会忘记运行它。 – max

+0

否则,您可以通过运行'rails g migration add_country_id_to_cities country_id:belongs_to'生成迁移。 – max