0

Ich habe eine Join-Tabelle für eine hat viele und gehört zu vielen durch, die Join-Tabelle mit vielen anderen Attributen hat einen Zeitstempel, Implementierung weise gibt es keine Probleme ,Fehler mit Minitest bekommen, wenn ich einen Zeitstempel für einen habe durch viele gemeinsame

Benutzer

class User < ApplicationRecord 

    has_many :affiliations 
    has_many :organizations, through: :affiliations 

end 

Organisation

class Organization < ApplicationRecord 

    has_many :affiliations 
    has_many :users, through: :affiliations 

end 

Zugehörigkeit

class Affiliation < ApplicationRecord 

    belongs_to :user 
    belongs_to :organization 

    has_many :xxxxxs 
end 

Affiliation speichert nicht nur das gehört, es hält selbst Informationen wie der Rang des Benutzers und was nicht in der Organisation ist. Es ist so ziemlich ein starkes eigenes Modell.

Für Armaturen, ich habe nicht eine Datei für die jointable noch

user.yml

user1: 
    email: [email protected] 
    organizations: org1 

organization.yml

org1 
    name: foo 

aber wenn ich laufen Tests mit Minitest, es gibt mir einen Fehler.

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) 

Seltsame ist, kommt es auf Tests, die nicht einmal die der Tisch nicht verwenden,

class PublicControllerTest < ActionController::TestCase 

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

Aktion absolut nichts an dieser Stelle seine einfach nur html

class PublicController < ApplicationController 
    def index 
    end 
end 

tut nichts in der Steuerung.

Sie gehen weg, wenn eine Zeitstempel entfernen, aber die Aufnahme, wenn die Verknüpfung erstellt wurde, ist die notwendige Information. Muss ich bei den Tests etwas tun?

Ich verwende Rails Edge (5.0.0rc1) Gibt es eine Chance, dass dies die Fehler verursacht?

+0

Könnten Sie den Test von Minitest setzen, die die Fehler produziert? Und vielleicht genaue Linie, die es verursacht? –

+0

Auch - funktioniert die Erstellung des gleichen gemeinsamen Datensatzes in Ihrem "normalen" Rails-Code? I.e. ist der Fehler nur für Minitest-Ausführung und nicht für anderen Code? –

+0

hinzugefügt Modelle, vollständige Fehler, tatsächliche Test und der Controller, den es testet, und ja, als Code im Projekt, funktioniert die ganze Sache ohne irgendein Problem – Saifis

Antwort

1

Update 3

Mit „Organisationen: org1“ für Ihre user1 in Seed-Daten Befestigungen - scheint dies das Problem verursacht, kann, da Benutzer nur durch Ihre gemeinsame Tabelle Organisation angeschlossen werden.

Ich habe nichts explizit in spec finden, aber etwas Relevantes 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.

Update 2.

ich falsch war bei Annahme, dass Sie nicht Zeitstempel in has_and_belongs_to_many jointable geschafft haben von Schienen.In der Tat wird innerhalb hasAndBelongsToMany Rails erstellen Sie eine Activerecord :: Base-Klasse für die Tabelle - here

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

Und Activerecord :: Base gehören Timestamp module

So sollte Ihr Fehler durch eine andere Art und Weise verursacht werden, zu schaffen, ein Eintrag in einer anderen als Standard Rails Association.


Original-.

Ich glaube nicht, dass Sie Zeitstempelfelder in der has_and_belongs_to_many-Beziehung in ActiveRecord automatisch verwaltet haben können. Dies funktionierte nicht (absichtlich) in alten Rails (z. B. 3.2 - Link unten), und es klingt nicht so, als ob es sich kürzlich geändert hätte.

Wenn Sie eine erweiterte Join-Tabelle haben möchten, können Sie ein dediziertes ActiveRecord-Modell dafür erstellen und verwenden Sie die Verknüpfung has_many: through. Auf diese Weise werden Zeitstempel automatisch unterstützt, wenn Sie sie zur Tabellendefinition hinzufügen.

Siehe https://github.com/rails/rails/issues/4653 für Zeitstempel auf 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.

Im Grunde ist dies aus einer Idee kommen können, dass Sie Activemodellklasse nicht für die jointable haben (2Update - Sie tatsächlich haben), und Zeitstempel sind Features des ActiveRecord-Modells. Zeitstempel in Rails 5.0rc1 hat sich nicht viel geändert - sources - Timestamp ist ein Modul, das ActiveRecord-Klasse erweitert.

By the way, ist es jetzt vorgeschlagen create_join_table Migration Helfer zu verwenden, die "reinen" Tisch (zwei IDs nur, keine Zeitstempel) schaffen: https://github.com/rails/rails/pull/4726

SO Frage mit ähnlichen Fehlern - 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.


Alternativ (Warnung - Theorie), können Sie versuchen, entweder Assoc mit iation Rückrufe oder Vereinigung Erweiterungen - 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

entschuldigen kann für die langsame Antwort, fügte einige weitere Informationen hinzu, ich zZ benutze eine hat viele durch, sorry aktualisiert den Titel – Saifis

0

Ihre Beziehungen zwischen den Modellen nicht durch eine Join-Tabelle dargestellt werden. Sie müssen durch eine reguläre Modelltabelle dargestellt werden (und sie benötigt id, created_at, updated_at). Sie sollten alle reguläre ActiveRecord :: Base-Modelle sein.

In diesem Fall haben Sie ein Modell beitreten, Zugehörigkeit und eine Join-Tabelle nicht

Also für alle drei, benötigen Sie einen regelmäßige aktive Datensatz Basistabelle (mit id, created_at, updated_at)

Join-Tabellen sind nur für has_and_belongs_to_many Verbände verwendet, und diese Tabellen erlauben ohne id, created_at, updated_at

+0

Ich glaube, dass alle von ihnen sind normale aktive Rekordmodelle, die "ApplicationRecord" ist, was Modelle von Rails 5 erben, keine Ahnung warum, aber sie änderten die Basis-Objektnamen http: // blog .bigbinary.com/2015/12/28/Anwendungsprotokoll-in-Schienen-5.html – Saifis