Rails 4: How to to save models in new form with has_many through association - ruby

I am new to rails, and I am trying to create a new event that allows a user to select a place and an organization from places and organizations that already exist in the database. I am using a has_many through association. Now I cannot get the event to save, even when I try to save the event without the place_id or organization_id fields.
Models:
class Event < ActiveRecord::Base
belongs_to :organization
belongs_to :place
end
class Organization < ActiveRecord::Base
has_many :events
has_many :places, through: :events
end
class Place < ActiveRecord::Base
has_many :events
has_many :organizations, through: :events
end
Event Controller:
def new
#event = Event.new
end
def create
#event = Event.new(event_params)
if #event.save
render 'show'
else
render 'new'
end
end
def event_params
params.require(:event).permit(:name, :description, :contact, :tag_list, :address, :latitude, :longitude, :long_description, :event_date, :start_time, :end_time, :organization_id, :place_id)
end
New Event View:
<%= form_for #event do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :event_date %>
<%= f.text_field :event_date %>
<%= f.label :start_time %>
<%= f.text_field :start_time %>
<%= f.label :end_time %>
<%= f.text_field :end_time %>
<%= f.label :description %>
<%= f.text_field :description %>
<%= f.label :contact %>
<%= f.text_field :contact %>
<%= f.label :address %>
<%= f.text_field :address %>
<%= f.label :long_description %>
<%= f.text_field :long_description %>
<%= f.label :tag_list, "Tags (separated by commas)" %>
<%= f.text_field :tag_list %>
<%= f.submit "Save event", class: "button" %>
<% end %>
What am I missing here to get the event to save, preferably with organization and place fields that have values of organization_id and place_id?

You should be looking at accepts_nested_attributes_for and fields_for.And then change your models to like this
class Organization < ActiveRecord::Base
has_many :events
has_many :places, through: :events
accepts_nested_attributes_for :places
end
class Place < ActiveRecord::Base
has_many :events
has_many :organizations, through: :events
accepts_nested_attributes_for :organizations
end
So that your event_params would be like this
def event_params
params.require(:event).permit(:name, :description, :contact, :tag_list, :address, :latitude, :longitude, :long_description, :event_date, :start_time, :end_time, places_attributes: [:some_attribute_of_place,..], organizations_attributes: [:some_attribute_of_organization,..)
end
And your form could be written as,
<%= form_for #event do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :event_date %>
<%= f.text_field :event_date %>
<%= f.label :start_time %>
<%= f.text_field :start_time %>
<%= f.label :end_time %>
<%= f.text_field :end_time %>
<%= f.label :description %>
<%= f.text_field :description %>
<%= f.label :contact %>
<%= f.text_field :contact %>
<%= f.label :address %>
<%= f.text_field :address %>
<%= f.label :long_description %>
<%= f.text_field :long_description %>
<%= f.label :tag_list, "Tags (separated by commas)" %>
<%= f.text_field :tag_list %>
<%= f.fields_for :places do |p| %>
---- your code-----
<% end %>
<%= f.fields_for :organizations do |o| %>
------ your code-----
<% end %>
<%= f.submit "Save event", class: "button" %>
<% end %>

Related

link_to expecting keyword_end rails

i don't understand why but i still have a problem when following the ruby on rails tutorial. It's when you put the links on to navigate between the different page..
this is my view:
<h1>New Article</h1>
<%= form_for #article, url: articles_path do |f| %> <!<%= form_for :article, url: articles_path do |f| %> >
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% #article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<%= link_to 'Back', articles_path %>
and this is my controller
class ArticlesController < ApplicationController
def new
end
def create
#article = Article.new(article_params)
if #article.save
redirect_to #article
else
render 'new' #on utilise render car cela permet de recharger la requête d'article
#qui vient d'échouer contrairement à redirect_to qui lancerais une nouvelle requete
end
end
def index
#articles = Article.all
end
def edit
end
def show
#article = Article.find(params[:id])
end
def update
end
def destroy
end
end
private
def article_params
params.require(:article).permit(:title, :text)
end
if you need some over tell me.
So if you have any tips, thanks a lot
Its not the link that is expecting end keyword. The actual error is due to no end tag to the form.
Please update yours as below
<h1>New Article</h1>
<%= form_for #article, url: articles_path do |f| %> <!<%= form_for :article, url: articles_path do |f| %> >
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<% #article.errors.full_messages.each do |msg| %>
<ul>
<li><%= msg %></li>
</ul>
<% end %>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<%end%>
<%= link_to 'Back', articles_path %>
It seems you have not initialized your #article variable in the new action.
In your new action write it as #article = Article.newand it should work fine.
As you have not initialized #article, it gives you a nil value error in the form.
Thanks for your quick answer, and i did what you told me to do. In fact I missed the end in the form. But now a new error comes which points the "heading" line 2:
Error message:
"First argument in form cannot contain nil or be empty"
The new code
<h1>New Article</h1>
<%= form_for #article url: articles_path do |f| %>
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% #article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<%end%>
<%= link_to 'Back', articles_path %>
Can you find the bug. I would like to improve myself in Ruby and Ror.
Thanks a lot

How to get one model value from another model in ruby on rails?

I got a task to integrate multiple models in a single form.I have one form 'register' and two models buyer and address. But by doing this i can not attach two forms together.
_form.html.erb is
<% #register.buyers.build %>
<%= form_for(#register) do |f| %>
<% if #register.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#register.errors.count, "error") %> prohibited this register from being saved:</h2>
<ul>
<% #register.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :date %><br />
<%= f.date_select :date %>
</div>
<div class="field">
<h4>Buyer</h4>
</div>
<div class="field">
<%# f.fields_for :buyers do |builder| %>
<%= render :partial => "buyer_fields", :locals => {:f => f } %>
<%# end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
_buyer_fields.html.erb is
<% f.fields_for :buyers do |buyers_form| %>
<div class="fields">
<p>
<%= buyers_form.label :name, "Name" %><br/>
<%= buyers_form.text_field :name %>
</p>
<h4>Address</h4>
<% f.fields_for :addresses do |builder| %>
<%= render :partial => 'address_fields', :locals => { :f => builder} %>
<% end %>
</div>
<% end%>
and the _address_fields.html.erb is
<p class="fields">
<table>
<tr>
<td>
<%= f.text_area :name, :rows => "2",:cols => "20" %>
</td>
</tr>
</table>
</p>
register model is
class Register < ActiveRecord::Base
attr_accessible :date, :book_ids,:buyers_attributes
has_many :authorships
has_many :books, :through => :authorships
has_many :buyers
#accepts_nested_attributes_for :buyers, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
accepts_nested_attributes_for :buyers, :allow_destroy => :true,
:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
end
buyer model is
class Buyer < ActiveRecord::Base
belongs_to :register
attr_accessible :addresses_attributes, :name
has_many :addresses, :dependent => :destroy
accepts_nested_attributes_for :addresses, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
end
and address model is
attr_accessible :name
belongs_to :buyer
But only register form is displayed. How can i integrate two models in single form in ruby on rails 3.2.9? Please help.
Your nested address view is wrong.
Make some changes in buyer_fields.html.erb
<%= f.fields_for :buyers do |buyers_form| %>
<div class="fields">
<p>
<%= buyers_form.label :name, "Name" %><br/>
<%= buyers_form.text_field :name %>
</p>
<h4>Address</h4>
<%= buyers_form.fields_for :addresses do |builder| %>
<%= render :partial => 'address_fields', :locals => { :f => builder} %>
<% end %>
</div>
<% end %>

can't convert Symbol into Integer + Rails 3.2 Nested Attributes

I'm working on a simple project to test the nested attributes of Rails 3.2. However, I'm getting this kind of error when trying to submit the form:
can't convert Symbol into Integer
post.rb and comment.rb
class Post < ActiveRecord::Base
attr_accessible :title, :comments_attributes
has_many :comments
accepts_nested_attributes_for :comments
validates_presence_of :title
end
class Comment < ActiveRecord::Base
attr_accessible :comment, :author
belongs_to :post
validates_presence_of :comment
validates_presence_of :author
end
posts_controller.rb
def new
#post = Post.new
#post.comments.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #post }
end
end
_form.html.erb
<%= form_for(#post) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<%= f.fields_for :comments_attributes do |builder| %>
<fieldset>
<%= builder.label :comment %><br />
<%= builder.text_field :comment %><br />
<%= builder.label :author %><br />
<%= builder.text_field :author %>
</fieldset>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
parameters
{"utf8"=>"✓",
"authenticity_token"=>"gNA0mZMIxkA+iIJjw8wsddcKxvmzaFnrgiHvFw1OrYA=",
"post"=>{"title"=>"Dummy Title",
"comments_attributes"=>{"comment"=>"Dummy Comment",
"author"=>"Dummy Author"}},
"commit"=>"Create Post"}
I agree with the comments that it's tough to troubleshoot without the stacktrace and create method, but that said, this looks weird:
<%= f.fields_for :comments_attributes do |builder| %>
The fields are for your comment objects, right? as opposed to the comment_attributes of the post object (the latter doesn't make sense here, at least on a first reading).
You might try changing :comments_attributes to :comments.

Fields_for Nested Model Rails 3.2.2

I have some nested models in my Rails application.
i have an article hat has mny properties.
class Article < ActiveRecord::Base
has_many :properties, :dependent => :destroy
accepts_nested_attributes_for :properties
end
class Property < ActiveRecord::Base
belongs_to :article
end
And now i want to edit this in my View so I editet the controler
# GET /articles/new
# GET /articles/new.json
def new
#article = Article.new
3.times { #article.properties.build }
respond_to do |format|
format.html # new.html.erb
format.json { render json: #article }
end
end
And also edited the View and the _format.html.erb
<%= form_for(#article) do |f| %>
<% if #article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#article.errors.count, "error") %> prohibited this article from being saved:</h2>
<ul>
<% #article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<% f.fields_for :properties do |prop| %>
<div class="field">
<%= prop.label :name %><br />
<%= prop.text_field :name %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
But there is no way to show up. If i want to create a new Model, i can not see any input fields for the properties.
What have i do wrong?
You're missing an = in your fields_for line. That is, it should be:
<%= f.fields_for :properties do |prop| %>

attr_accessible with paperclip multiple picture uploads

I followed the tutorial here and everything turned out nicely.. until I tried adding attr_accessible to the article model. Thanks in advance.
Here's the related code:
app/models/user.rb
class User < ActiveRecord::Base
attr_accessible :name, :email
has_many :assets, :dependent => :destroy
accepts_nested_attributes_for :assets, :allow_destroy => true
end
app/models/asset.rb
class Asset < ActiveRecord::Base
attr_accessible :user_id, :image
belongs_to :user
has_attached_file :image,
:styles => {
:thumb=> "100x100#",
:small => "300x300>",
:large => "600x600>"
}
end
db/schema.rb
create_table "assets", :force => true do |t|
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
end
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at"
t.datetime "updated_at"
end
app/views/users/_form.html.erb
<%= form_for(#user, :html => { :multipart => true }) do |f| %>
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="newPaperclipFiles">
<%= f.fields_for :assets do |asset| %>
<% if asset.object.new_record? %>
<%= asset.file_field :image %>
<% end %>
<% end %>
</div>
<div class="existingPaperclipFiles">
<% f.fields_for :assets do |asset| %>
<% unless asset.object.new_record? %>
<div class="thumbnail">
<%= link_to( image_tag(asset.object.image.url(:thumb)), asset.object.image.url(:original) ) %>
<%= asset.check_box :_destroy %>
</div>
<% end %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
After trying various permutations and going through related posts, finally caught the gremblin that's been eluding me the past few days. All I needed is to add the :assets_attributes to the list of attr_accessible in the user model. Thanks for reading!
attr_accesible for nested objects

Resources