2016-07-13 16 views
0

Ich habe ein Benachrichtigungssystem in meiner App. Wenn der Benutzer auf die Seite eines anderen Benutzers (Benutzer/Seite anzeigen) wechselt, wird die Benachrichtigungsanzahl verringert, da er das gemeinsame Chatfenster sehen kann. Wenn Sie also zum Beispiel eine SMS an Sie gesendet haben, haben Sie eine Benachrichtigung. Wenn Sie auf der Senderseite des Absenders ankommen, werden Ihre Benachrichtigungen auf 0 reduziert.Schienen Controller Aktion + Rendering Bug

Alles hat gut funktioniert, aber ich wollte den Code umgestalten, da er unübersichtlich wurde.

Darunter können Sie den alten und den neuen Code sehen. Der alte Code funktioniert gut, aber es gibt ein seltsames Problem mit dem neuen Code. Wenn ich auf die Benutzerseite komme und das Attribut current_user.new_chat_notification in der Controller-Show-Aktion oder in der Vorlage (ich zeige es in der Kopfzeile, so dass es auf jeder Seite verfügbar ist) ausdruckt, zeigt es 1. In der Zwischenzeit, wenn ich die Nummer ausdrucke in der Konsole zeigt es 0 an. Aus irgendeinem Grund wird die Zahl in der db verringert, aber die Controller-Aktion und die Ansicht wissen nicht rechtzeitig darüber. Wenn ich auf eine andere Seite gehe, geht die Nummer auf Null. Die nächste Controlleraktion weiß also bereits, dass die Zahl verringert wurde und 0 anzeigt. Ich verstehe nicht wirklich, was der Unterschied zwischen dem alten und dem neuen Code ist, der so etwas verursachen kann.

schema.rb

create_table "users", force: :cascade do |t| 
    t.integer "new_chat_notification", default: 0 
end 

Benutzer Controller

def show 
    @user = User.find(params[:id]) 
    #FOLLOWING 3 LINES ARE PART OF THE UPDATE 
    @conversation = Conversation.create_or_find_conversation(current_user.id, @user.id) 
    @tasks = Task.uncompleted.between(current_user.id, @user.id).order("created_at DESC").includes(:assigner, :executor).paginate(page: params[:page], per_page: 14) 
    @messages = @conversation.messages.includes(:user).order(created_at: :desc).limit(50).reverse 
    current_user.decreasing_chat_notification_number(@user) 
    respond_to do |format| 
    format.html 
    format.js { render template: "tasks/between.js.erb" } 
    end 
end 

user.rb

#FOLLOWING 2 LINES ARE PART OF THE UPDATE 
has_many :notifications, foreign_key: "recipient_id", dependent: :destroy 
validates :new_chat_notification, numericality: { only_integer: true, greater_than_or_equal_to: 0 } 

def decreasing_chat_notification_number(sender) 
    notification = notifications.between_chat_recipient(sender).unchecked.first 
    checking_and_decreasing_notification(notification) if notification.present? 
end 

def checking_and_decreasing_notification(notification) 
    notification.check_notification 
    if notification.notifiable_type == "Message" 
    # decrease_new_chat_notifications --> OLD CODE THAT WORKING PROPERLY 
    NotificationSender.new(notification).decrease_new_chat_notifications # --> NEW CODE NOT WORKING PROPERLY 
    .... 
    else 
    .... 
    end 
end 

def decrease_new_chat_notifications 
    decrement!(:new_chat_notification) if new_chat_notification > 0 
end 

notification_sender.rb (für neuen Code)

class NotificationSender 
    attr_reader :notification, :recipient 

    def initialize(notification) 
    @notification = notification 
    @recipient = notification.recipient 
    end 

    def decrease_new_chat_notifications 
    recipient.decrement!(:new_chat_notification) if recipient.new_chat_notification > 0 
    end 
end 

Antwort

1

Der Unterschied ist, dass diese Linie in der Tatsache sein kann:

@recipient = notification.recipient 

kann den Empfänger aus der Datenbank laden, um den Zustand zurückzusetzen. Es ist nicht offensichtlich aus Ihrem Code, ob es eine Zustandsänderung im User Modell gibt, bevor die decreasing_chat_notification_number aufgerufen wird.

UPDATE

Wenn dies tatsächlich der Grund für das Problem (die derzeit nur ein nicht unterstützter Vorschlag ist), könnten Sie Ihren referenzierten Empfänger zusammen mit der Benachrichtigung laden. Auf diese Weise wird der It-Status nicht unerwartet von der Datenbank aktualisiert, wenn Sie die NotificationSender initialisieren.

Statt notification = notifications.between_chat_recipient(sender).unchecked.first, versuchen Sie dies:

notification = notifications. 
    between_chat_recipient(sender). 
    unchecked. 
    includes(:recipient). 
    first 

Die genaue Abfrage unterschiedlich sein kann je nach Verbänden, aber auch hier ist die Idee, den Empfänger in dem gleichen Datenbank-Aufruf als Benachrichtigung zu laden, so dass das Entfernen die mögliche Race-Bedingung.

+0

Nic, was meinst du mit "es ist nicht offensichtlich aus deinem Code"? Soll ich noch etwas anderes zeigen? Wenn das das Problem ist, was du sagst, was soll ich im Code ändern, damit es funktioniert? –

+0

Entschuldigung, ich habe die Empfehlungen nicht angegeben. Siehe meine aktualisierte Antwort. "Nicht offensichtlich" bedeutet, dass es wahrscheinlich einige andere Teile des Codes gibt, die eine Rolle spielen könnten, aber es ist nicht klar, ob sie im Controller oder im Modell oder in beiden enthalten sind.Versuchen Sie zuerst die Empfehlung, und wenn das Problem dadurch nicht behoben wird, fügen Sie bitte den vollständigen Code der Aktion "users # show" und das Modell "User" zu Ihrer Frage hinzu. –

+0

Nic, fügte die relevanten Teile hinzu. Es gibt auch Pusher gem für Live-Benachrichtigungen, aber wenn ich den Pusher-Trigger-Teil von der Methode 'checking_and_decreasing_notification' in der user.rb lösche (wo ich' .... 'habe), ist das Problem immer noch da. Auf der anderen Seite der if else-Anweisung gibt es other_notifications, die wie Chat-Benachrichtigungen funktionieren, nur der notificable_type ist anders. Ich habe das gleiche Problem damit, nur versucht, die Frage zu trimmen. Ich habe deine Lösung versucht, aber nicht funktioniert. Es ist super komisch, da ich den Unterschied zwischen dem alten und dem neuen Code nicht sehe. –

Verwandte Themen