2016-03-11 2 views
1

Я задал этот вопрос по-другому, но удалил его, чтобы сделать более ясностью.Rails has_many: сквозной с уникальностью

У меня есть модель статьи. Он имеет несколько контактов, через:: article_contacts.

У меня есть контактная модель. Это has_many статьи, через:: article_contacts.

Мне нужен каждый контактный объект, чтобы быть уникальным, но быть в состоянии быть связанным с разными статьями. Мой последний вопрос привел к тому, что люди показывали мне, как показывать только уникальные контакты, или проверять модель соединения, но это не то, что мне нужно.

мне нужно, например, таблицы, как следующее:

Article 
id: 1, name: "Whatever", content: "Whatever" 
id: 2, name: "Again, whatever", content: "Whateva" 

Contact 
id: 1, email: "[email protected]" 
id: 2, email: "seconde[email protected]" 

ArticleContact 
id: 1, article_id: 1, contact_id: 1 
id: 2, article_id: 1, contact_id: 2 
id: 3, article_id: 2, contact_id: 1 

Итак, когда я строй ассоциации в моем контроллере статьи в новом действии, и я призываю @ article.save в создании действий, я получить вставку новой статьи, вставить контакт и вставить статью_relationship. Отлично.

НО, в статье 2, если я добавлю то же письмо в контактную форму, я не хочу создавать другой Контакт с тем же письмом. Но я хочу (как вы видите, с третьим ID в ArticleContact выше) для создания. Но каждый вызов @ article.save делает это. Я попытался first_or_initialize и < < в коллекцию, но он всегда создает несколько раз, и если у меня есть проверка, это означает, что я не могу создать отношения ArticleContact, потому что контакт уникален.

В конечном итоге у меня может быть папка с контактами, но я подозреваю, что она будет длинной, поэтому я бы просто просто ввел электронное письмо в форму и проверил код, что он уникален, и если да, просто создайте соединение с использованием существующего идентификатора.

Это должно быть легче, чем я понимаю, но я не могу найти ни одной статьи, которая демонстрирует это где угодно.

Обновлено с кодом за запрос, однако, опять же, у меня нет кода, который только создаст уникальный контакт и свяжет отношения с существующим. Вот что мне не хватает, поэтому этот код покажет только то, что я уже знаю, а не как добраться до того, что я хочу :).

ArticleController:

def new 
    @article = @business.articles.build 
    authorize @business 
    @article.attachments.build 
    @article.contacts.build 
end 

def create 
    @article = @business.articles.new(article_params) 
    authorize @business 

    respond_to do |format| 
    if @article.save 
     format.html { redirect_to business_article_path(@business, @article), notice: "Knowledge created." } 
    else 
     format.html { render 'new' } 
    end 
    end 

end 

Модель имеет стандартный has_many: thruogh и принадлежит. Я могу показать это, но они верный путь. Просмотр только стандартный simple_form здание контакт:

<%= f.simple_fields_for :contacts, class: "form-inline" do |contact| %> 
    <%= contact.input :first_name, label: "Contact First Name" %> 
    <%= contact.input :last_name, label: "Contact Last Name" %> 
    <%= contact.input :email, label: "Contact Email" %> 
    <% end %> 
+0

Добавив контроллеров, моделей и код просмотра поможет диагностировать проблему. – Dharam

+0

Я могу, но это очень котельная плита. Я подозреваю, что код, который у меня есть, делает именно то, что он должен, т. Е. Строить связь и сохранять, сохранять контакт и ассоциацию. Мне нужно, чтобы он был более сложным и не знал, как, но я поставлю там плиту котла :). – Art

+0

Как вы назначаете «контакт» в 'article' в' article_controller'? – Dharam

ответ

1

Вы должны обеспечить уникальность, только в случае, если:

# contact.rb 
class Contact 
    ... 
    validates_uniqueness_of :email 
    ... 
end 

Но в вашем контроллере вы можете сделать:

# articles_controller.rb 
def create 
    ... 
    # we can rely on it's uniqueness 
    contacts << Contact.find_or_create_by(email: param[:email) 
    ... 
end 

или любой другой наилучшим образом соответствует вашим потребностям.

Надеюсь, это поможет!

+0

Благодарим за ответ. Я не хочу применять уникальность при подаче формы. Я знаю, что люди будут отправлять одно и то же электронное письмо более одного раза. Если я проверю на: электронной почте, которую я пробовал, я просто получаю стандартную ошибку формы, в которой сообщение электронной почты уже принято. Я знаю. Мне нужно, чтобы он принял дубликат при отправке формы, но затем создайте только добавьте этот параметр. Ваше создание выглядит правильно. Я пробовал это, но он добавляет дважды, потому что @ article.save сохраняет его в первую очередь. – Art

+0

Итак, мне пришлось удалить contacts_attributes из представления формы, чтобы whitelisted_params = article_params, а затем удалили из белых параметров. Это позволило мне использовать это для создания контакта отдельно и сохранить его уникальным. Я подтвержу завтра, но пока это единственный способ сохранить @ article.save от сохранения контакта. – Art

1

укажите вашу статью. Контактируйте с валидацией.

validates :article_id, unique {scope: :contact_id} 

это не позволит вам иметь ArticleContacts, которые являются точно такими же.

при создании контакта, попробуйте:

contact = Contact.where(email: "[email protected]:").first_or_create 

в contact.rb

validates :email, uniqueness: true 
+0

Это сработает, и я попробовал это, но @ article.save фактически вставляет мне контакт. Мне не дают шанс построить его на стороне. Это мое замешательство. – Art

+0

лично, я сделал бы это вместо того, чтобы строить контакт прежде по этой причине. Создайте его самостоятельно, если @ article.save и избавиться от сборки. должно сработать. – toddmetheny

0

Вы могли бы попробовать это в методе создания

verified_contacts = [] 

@article.contacts.each do |contact| 
    existing_contact = Contact.find_by(email: contact.email) 
    verified_contacts << (existing_contact || contact) 
end 

@article.contacts = verified_contacts 
Смежные вопросы