Reputation: 1428
I am new to Rails and struggling to get a formtastic form to save - the database keeps rolling back the insertion without any apparent explanation.
I have a PublishedItem and a Citation. Each PublishedItem can have many references to other PublishedItems via Citation - here is the (stripped down) PublishedItem model:
class PublishedItem < ActiveRecord::Base
attr_accessible :date_published,
:author_ids,
:cited_published_item_ids,
:citing_published_item_ids
has_many :authorships
has_many :authors, through: :authorships, order: "last_name, first_name"
has_many :citations,
foreign_key: "citing_published_item_id",
class_name: "Citation",
dependent: :destroy
has_many :cited_published_items,
through: :citations,
source: :cited
has_many :reverse_citations,
foreign_key: "cited_published_item_id",
class_name: "Citation",
dependent: :destroy
has_many :citing_published_items,
through: :reverse_citations,
source: :citing
There are other relationships, but I have only included one for comparison purposes: The Authorship relationship, a more typical relationship to another table, Authors save properly. It is just the self-referencing one where I am having a problem.
Here is the Citations Model:
class Citation < ActiveRecord::Base
attr_accessible :citation_type, :cited_id, :citing_id
belongs_to :citing,
class_name: "PublishedItem",
foreign_key: "citing_published_item_id"
belongs_to :cited,
class_name: "PublishedItem",
foreign_key: "cited_published_item_id"
And the table (postgresql):
CREATE TABLE citations
(
id serial NOT NULL,
citing_published_item_id integer,
cited_published_item_id integer,
citation_type character varying(255),
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
CONSTRAINT published_item_citations_pkey PRIMARY KEY (id )
)
WITH (
OIDS=FALSE
);
The new.html.erb form (extract):
<%= semantic_form_for @published_item do |f| %>
<%= f.semantic_errors %>
<%= f.inputs do %>
<%= f.input :title %>
<%= f.input :authors, as: :select,
collection: Author.find(:all, order: "last_name ASC, first_name ASC") %>
<%= f.input :cited_published_items, as: :select,
collection: PublishedItem.find(:all, order: "title ASC") %>
<% end %>
<%= f.actions do %>
<%= f.action :submit, button_html: { class: "btn btn-primary" } %>
<%= f.action :cancel, button_html: { class: "btn btn-default" } %>
<% end %>
What I would like to have happen, and cannot seem to achieve, is to reference another PublishedItem being passed into the new PublishedItem form, and insert a record into Citations with the original PublishedItem as cited_published_item, and the new PublishedItem as the citing_published_item. But I am stumped. Whenever I select a PublishedItem in the select list, the query rollsback. Authorship (and other M:M) work properly.
Any help greatly appreciated.
Upvotes: 1
Views: 205
Reputation: 12564
try something like this -
controller :
def new
@published_item = PublishedItem.new
@published_item.citations.build
end
PublishedItem model :
accepts_nested_attributes_for :citations
# i noticed your accessible foreign keys were set wrong here
attr_accessible :citation_type,
:cited_published_item_id,
:citing_published_item_id
form :
<%= semantic_form_for @published_item do |form| %>
# published_item fields
<%= form.fields_for :citations do |citation_subform| %>
<%= citation_subform.select :cited_published_item_id,
options_for_select(
PublishedItem.order(:title).map{|p|[p.title,p.id]}
) %>
<% end %>
<% end %>
you want your form to pass params structured like this :
{published_item :
{citations_attributes:
[
{cited_published_item_id: xxx}
]
}
}
Upvotes: 1