0

Ich habe 2 Tabellen schools und private_schools und sie sind nicht miteinander verwandt. Was ich tun muss, ist die Daten aus beiden Tabellen zu durchsuchen, um die Ergebnisse zu füllen.So erhalten Sie Daten aus 2 Tabellen basierend auf Suchschlüsselwortschienen

Beide Tabellen hat das Attribut name, von denen ich Ergebnisse erhalten muss. Wenn der Benutzer also ein Schlüsselwort schreibt, werden die Daten in beiden Tabellen gesucht.

Hier ist die Abfrage, die ich versuche, aber es gibt Fehler zurück.

Abfrage:

User.includes(:schools, :private_schools).where("schools.name = ? or 
private_schools.name = ?", params[:keyword]) 

Ich weiß, die User. Art der Sache ist auch nutzlos und ist auch nicht nötig, aber wie sollten wir dieses Problem bewältigen Keywords aus beiden Tabellen zur gleichen Zeit suchen?

Fehler ist:

Active :: PreparedStatementInvalid (falsche Anzahl von Bind-Variablen (1 für 2) in: schools.name = oder private_schools.name =?):

Per Kommentare der Code Modelle sind:

private School:

class PrivateSchool < ActiveRecord::Base 
    belongs_to :teacher 
    has_many :private_school_specializations, :dependent => :destroy 
    has_many :private_classes 
    has_many :invitation_promo_codes 
    has_many :popular_schools, as: :resource, :dependent => :destroy 
end 

School:

class School < ActiveRecord::Base 
    belongs_to :user 
    has_many :students 
    has_many :subjects 
    has_many :teachers 
    has_many :departments 
    has_many :student_ids 
    has_many :teacher_ids 
    has_many :class_rooms 
    has_many :popular_schools, as: :resource, :dependent => :destroy 
end 

Benutzer:

class User < ActiveRecord::Base 
    has_one :school 
    has_one :student 
    has_one :teacher 
    accepts_nested_attributes_for :student 
    accepts_nested_attributes_for :teacher 
end 
+0

Schreibe den Code dieser drei Modelle –

+0

@ShamsulHaque hinzugefügt Modellcode. – LearningROR

+0

Was möchten Sie von den beiden Tischen bekommen? Sind die Datenausgaben ähnlich? Wenn nicht, benötigen Sie zwei separate Abfragen. Andernfalls können Sie a. Ordne die Ergebnisse in zwei Arrays zu und verbinde sie. So haben Sie eine Reihe von Ergebnissen, keine Sammlung. b. Run raw sql Abfrage –

Antwort

1

Ich habe einige Dinge für Sie:

  1. Die includes wird verwendet, um Beziehungen zu spezifizieren in der Ergebnismenge enthalten sein. Sie haben also keine Beziehung zwischen schools und private_schools. Also die direkte können Sie nicht so abfragen, weil Sie nicht zwei Tabellen join keine Beziehung haben können. Sie können eine separate Abfrage für jede Tabelle school und private_school durchführen.

    schools = School.where(name: params[:name]) 
    schools << PrivateSchool.where(name: params[:name]) 
    schools.flatten! 
    

Sie können beide wie dies in ein Array setzen und dann die Schleife auf der Ansicht. Um nur die Namen zu entfernen, die Sie hinzufügen können:

pluck(:name) 

Das umfasst ist eine andere Sache. Wie zum Beispiel:

User.includes(:posts).where('posts.name = ?', 'example') 

wenn die Post zum User gehören so etwas passieren wird, ist die include die posts geladen wird, und wenn Sie versuchen, die posts mit example Namen zu holen wäre es keine zusätzliche Abfrage Feuer da es Diese Daten sind bereits geladen. Das funktioniert nur, wenn Sie eine Beziehung zwischen den Modellen haben.

  1. Die school und private_school können ein einzelnes Modell sein, wenn die Attribute beider identisch sind.Sie können einfach ein Attribut von is_private hinzufügen, das boolesch ist und dessen Wert true im Falle von Privatschulen ist. (Dies wird auf Ihre Attribute abhängig)
+0

Ich möchte für Option 1 gehen. Gibt es ein Beispiel, wie beide Abfragen in einer Methode ausgeführt werden, die nach Suchschlüsselwort suchen? Danke – LearningROR

+0

So werden Sie zwei Abfragen für es in einer Methode schreiben und Sie können sie in einem Array hinzufügen. Ich habe die Antwort aktualisiert. – Deep

2

Fehler festgestellt Grund Die folgende Abfrage erwartet zwei params, eine an jeder ?

User.includes(:schools, :private_schools).where("schools.name = ? or 
private_schools.name = ?", params[:keyword]) 

So

User.includes(:schools, :private_schools).where("schools.name = ? or 
private_schools.name = ?", params[:keyword], params[:keyword]) 

Oder nur

User.includes(:schools, :private_schools).where("schools.name = :name or 
private_schools.name = :name", name: params[:keyword]) 

ERWARTEN SIE ETWAS?

Ich kenne den Benutzer. eine Sache ist auch nutzlos und wird auch nicht benötigt, aber wie sollten wir dieses Problem lösen, um Keywords aus beiden Tabellen gleichzeitig zu durchsuchen?

Eigentlich Ihre User. Abfrage wird eine Liste der Benutzer und nicht eine Liste von Schulen oder private_schools zurückkehren, so dass, wenn Sie erwarten keine Liste der Benutzer, die Sie für etwas anderes suchen könnte ... vielleicht eine Liste der Schulen ?

Wenn Ihre schools und private_schools die gleiche Struktur haben, sollten Sie einen Blick in inheritance werfen und die gleiche Tabelle für beide Modelle verwenden. Vorerst Sie so etwas wie tun könnte:

def my_result 
    schools = School.where(name: params[:name]).to_a 
    private_schools = PrivateSchool.where(name: params[:name]).to_a 
    schools + private_schools # combine both arrays 
end 
+0

Ich finde 'User.' ist nicht notwendig, da ich nur die Ergebnisse aus beiden Tabellen abfragen möchte, ohne' User' zu berücksichtigen. 'User' wird nicht benötigt, da ich oben dasselbe gepostet habe. Können wir das ohne "User" Faktor machen? – LearningROR

+0

Wenn die Tabellen nicht verwandt sind, müssten Sie zwei separate Abfragen durchführen ... 'Benutzer.wird eine Liste der Benutzer in diesen Bedingungen und nicht eine Liste der Schulen oder private_schools zurückgeben, also nicht sicher, was Sie suchen – gabrielhilal

+0

Ja , Würde ich gerne getrennte Abfragen machen, können wir das in der gleichen Methode verwalten? Ihre Kommentare ergeben sich jetzt für mich. Bitte entschuldigen sie. – LearningROR

0

Wenn Sie das tun wollen „komplexe“ Abfragen wie dies häufig in Ihrer Anwendung, empfehle ich Ihnen, überprüfen Sie die „plündern“ gem. Es macht Abfragen wie diese ein Kinderspiel, und Ihre Codebasis sauber.

MyModel.search(:private_school_name_or_school_name_cont => params[:q).result 

ref: https://github.com/activerecord-hackery/ransack

Verwandte Themen