0

我有一个连接表有很多并且属于很多通过,连接表包括很多其他属性都有一个时间戳,实现明智没有问题,用Minitest获取错误时我有一个有很多通过jointable的时间戳

用户

class User < ApplicationRecord 

    has_many :affiliations 
    has_many :organizations, through: :affiliations 

end 

组织

class Organization < ApplicationRecord 

    has_many :affiliations 
    has_many :users, through: :affiliations 

end 

所属

class Affiliation < ApplicationRecord 

    belongs_to :user 
    belongs_to :organization 

    has_many :xxxxxs 
end 

所属商店不仅仅属于它,它本身拥有诸如用户级别和组织内部不存在的信息。它几乎是一个强大的模型。

对于赛程,我没有一个文件的jointable然而,

user.yml

user1: 
    email: [email protected] 
    organizations: org1 

organization.yml

org1 
    name: foo 

但是当我使用MINITEST运行测试,它给了我一个错误。

Error: 
PublicControllerTest#test_should_get_index: 
ActiveRecord::StatementInvalid: Mysql2::Error: Field 'created_at' doesn't have a default value: INSERT INTO `affiliations` (`user_id`, `dominion_id`) VALUES (794918725, 299359653) 

奇怪的是,它发生在甚至不使用上述表格的测试,

class PublicControllerTest < ActionController::TestCase 

    test "should get index" do 
    get :index 
    assert_response :success 
    end 
end 

这个动作绝对没有,在这一点上它只是普通的HTML

class PublicController < ApplicationController 
    def index 
    end 
end 

在控制器中不做任何事情。

当删除时间戳时它们会消失,但创建关联时记录是必要的信息。在测试中我需要做些什么?

我正在使用Rails边缘(5.0.0rc1)有没有可能导致错误?

+0

你能不能把由产生错误MINITEST测试?也许确切的线路导致它? –

+0

另外 - 在你的“普通”Rails代码中创建相同的连接表记录是否有效?即是minitest只运行的特定错误,而不是其他代码? –

+0

增加的模型,完整的错误,实际测试和它测试的控制器,是的,作为项目中的代码,整个事情没有任何问题 – Saifis

回答

1

更新3

“组织:ORG1”在灯具种子数据的用户1 - 看来这是造成问题,因为用户只能通过您的接合表连接到组织。

我没有发现任何东西在规范明确,但相关的事情here

Fixtures bypass the normal Active Record object creation process. After reading them from YAML file, they are inserted into database directly using insert query. So they skip callbacks and validations check. This also has an interesting side-effect which can be used for drying up fixtures.

更新2

我错了,在假设你不能在has_and_belongs_to_many jointable时间戳管理由Rails。事实上,HasAndBelongsToMany钢轨内侧将创建一个ActiveRecord :: Base类为表 - here

def through_model 
    habtm = JoinTableResolver.build lhs_model, association_name, options 
    join_model = Class.new(ActiveRecord::Base) { 
    class << self; 
    ... 

而且ActiveRecord的::基地包括时间戳module

所以,你的误差应通过建立某种其他方式造成的jointable中的条目,然后是标准Rails关联。


原始

我不相信你可以在连接表中自动管理ActiveRecord中has_and_belongs_to_many关系的时间戳字段。这并没有(有意)在旧的Rails中工作(例如3.2以下的链接),并且听起来不像它最近改变了。

如果你想扩展连接表,你可以为它创建一个专用的ActiveRecord模型,并使用has_many:through关联使用。这样,如果将它添加到表定义中,它将自动支持时间戳。

的时间戳见https://github.com/rails/rails/issues/4653上HABTM jointable

AFAICT Rails 3.1 does not populate timestamps on a join table. The only difference is that in 3.2, when you add timestamps, they are marked as NOT NULL.

@veganstraightedge the timestamps didn't "work" in 3.1 - they just didn't raise an error when the join table was saved with them as null. the difference here is that in 3.2 timestamps are created with a NOT NULL constraint.

基本上,这可能来自你没有ActiveRecord的模型类的jointable的想法(更新2 - !其实你有)和时间戳是ActiveRecord模型的特征。 Rails 5.0rc1中的时间戳没有太大改变 - sources - Timestamp是一个扩展ActiveRecord类的模块。

顺便提一下,它现在建议使用create_join_table迁移助手,将创建“纯粹”表(只有两个ID的,没有时间戳): https://github.com/rails/rails/pull/4726

SO 问题有着相近的错误 - Rails 3.2 + MySQL: Error: Field 'created_at' doesn't have a default value: INSERT INTO

Rails 3.2 doesn't automatically populate the timestamp fields for join tables of :habtm relationships.


或者(警告! - 理论),你可以尝试使用任一副教授iation回调或协会扩展 - http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

Association callbacks

Similar to the normal callbacks that hook into the life cycle of an Active Record object, you can also define callbacks that get triggered when you add an object to or remove an object from an association collection.

class Project 
    has_and_belongs_to_many :developers, after_add: :evaluate_velocity 

    def evaluate_velocity(developer) 
    ... 
    end 
end 

Extensions

The extension argument allows you to pass a block into a has_and_belongs_to_many association. This is useful for adding new finders, > creators and other factory-type methods to be used as part of the association.

has_and_belongs_to_many :contractors do 
    def find_or_create_by_name(name) 
    first_name, last_name = name.split(" ", 2) 
    find_or_create_by(first_name: first_name, last_name: last_name) 
    end 
end 

Extensions can refer to the internals of the association proxy using these three attributes of the proxy_association accessor:

proxy_association.owner returns the object that the association is a part of. 
proxy_association.reflection returns the reflection object that describes the association. 
proxy_association.target returns the associated object for belongs_to or has_one, or the collection of associated objects for has_many or has_and_belongs_to_many. 
+0

对于慢速响应感到抱歉,增加了一些更多的信息,我目前使用了一个有很多通过,对不起更新标题 – Saifis

0

你的模型之间的关系不能由一个连接表来表示。他们需要用一个常规的模型表来表示(它需要id,created_at,updated_at)。它们应该都是常规的,ActiveRecord :: Base模型。

在这种情况下,你有一个加盟模式,隶属关系,而不是连接表

因此,对于所有三个,你需要一个固定的积极备案基地台(含ID,created_at,的updated_at)

加入表只用于has_and_belongs_to_many协会,这些都允许与没有id,created_at表的updated_at

+0

我相信他们都是正常的活动记录模型,“ApplicationRecord”是什么模型从Rails 5继承,不知道为什么,但他们改变了基本对象名称http:// blog .bigbinary.com/2015/12/28 /人应用记录在护栏-5.html – Saifis