2016-07-13 11 views
0

Dies könnte der falsche Weg sein, dies vollständig zu tun, und ich bin sehr offen für Alternativen.Skip has_many: durch Model Creation auf keine Änderung

Ich habe folgende Modelle bekommt, wo UsersPositions viele haben:

class User < ApplicationRecord 
    has_many :user_positions 
    has_many :positions, through: :user_positions 

    accepts_nested_attributes_for :user_positions, 
    reject_if: :all_blank 
end 

class UserPosition < ApplicationRecord 
    belongs_to :user 
    belongs_to :position 
end 

class Position < ApplicationRecord 
end 

Auf meinem bearbeiten Benutzerformular, würde Ich mag eine User ‚s aktuelle Position aktualisiert werden können. Ich, dass in der folgenden Art und Weise:

<%= form_for @user do |f| %> 
    <%= f.label :name %> 
    <%= f.text_field :name %> 

    <%= f.fields_for :user_positions, @user.user_positions.order(created_at: :desc).first do |ff| %> 
    <%= ff.hidden_field :user_id, value: @user.id %> 
    <%= ff.collection_select :position_id, Position.all, :id, :label %> 
    <% end %> 

    <%= f.submit "Update User" %> 
<% end %> 

Das Problem, das ich in laufen lasse, ist, dass eine neue Instanz von UserPosition wird jedes Mal, wenn ich das Formular erstellt werden, auch wenn die Position, die nicht geändert ausgewählt sind hat. Dies führt zu einer Reihe von doppelten Einträgen in der Join-Tabelle, wenn es mir wirklich nur um "Promotions" oder "Herabstufungen" geht, wenn sich der Wert von position_id geändert hat.

Ich möchte keinen benutzerdefinierten Validator hinzufügen, um die Erstellung zu verbieten, da ich immer noch möchte, dass das Formular mit einer unveränderten Position übergeben werden kann. Ein Beispiel dafür ist, wenn ich nur den Namen User ändern möchte.

Haben Sie Ratschläge zum Umgang mit diesem Anwendungsfall?

Antwort

0

Es stellt sich heraus, dass Sie tatsächlich jede Methode als Symbol Argument die accepts_nested_attributes_forreject_if Option verwenden können.

ich meine User Modell wie folgt aktualisiert, und jetzt ist das Verhalten genau das, was ich will:

class User < ApplicationRecord 
    has_many :user_positions 
    has_many :positions, through: :user_positions 

    accepts_nested_attributes_for :user_positions, 
    reject_if: :same_as_previous_position 

    def same_as_previous_position(attributes) 
    if self.user_positions.empty? 
     return false 
    end 

    Position.find(attributes[:position_id]) == self.user_positions.order(created_at: :desc).first.position 
    end 
end