Nested attributes with polymorphic has_many model - forms

I am trying to figure out what is the best way to go about creating a model like "Article" and another model that is a polymorphic model called "comment". The reason I want to do this is so I don't have duplicate models for comments. So at this point I have the polymorphic model up and running and working with the article model. The problem is I want everything to be on one form. The Ability to edit the article and post a comment. Any suggestions would help me out with this dilemma.

This can be achieved using form_tag
<%= form_tag :url => , :html => {:id=> , :method => , :class => ""} do %>
<% text_field_tag <id>, <default_value>, :name=>"article[title]" %>
<% text_field_tag <id>, <default_value>, :name=>"article[content]" %>
<% text_area_tag <id>, <default_value>, :name=>"comment[id]" %>
<% text_area_tag <id>, <default_value>, :name=>"comment[id+1]" %>
<%= submit_tag 'save' %>
<% end %>
the params will then nicely be grouped in a hash like
{'article' => {'title' => , 'content' => }, 'comment' => {'1' => , '2' => . . .}}
which you can parse to update both the models.

Related

In RoR, f.fields_for is rendering as nothing

I’m using Rails 4.2.7. In my model I have
class MyObject < ActiveRecord::Base
…
belongs_to :address, :autosave => true, dependent: :destroy
accepts_nested_attributes_for :address, :my_object_times
and the address model
class Address < ActiveRecord::Base
belongs_to :state
belongs_to :country
...
has_one :my_object
end
I want to write a form that will allow me to build both the child and parent objects, so I tried
<%= form_for #my_object, :url => my_objects_create_path, :remote => true do |f| %>
<div class="field">
<%= f.fields_for :address do |addr| %>
<%= addr.label :address %> <span name="my_object[address]_errors"></span><br>
City: <%= addr.text_field :city %>
<%= addr.select :state, options_for_select(us_states.collect{|s| [ s.name, s.id ]}), {:prompt => "Select State"} %>
<%= country_code_select('my_object[address]', 'country_id',
[[ 'US', 'United States' ], [ 'CA', 'Canada' ]],
{:include_blank=>true, :selected => #default_country_selected.id},
{:class=>'countryField'}
) %>
<% end %>
</div>
but the above is rendered as only
<div class="field">
</div>
How do I adjust things so that my fields render AND I'm able to create my object in my controller using
my_object = MyObject.new(params)
Edit: Per the answer given, I tried
#my_object.address.build
from teh controller action taht rendres the form, but got the erorr
undefined method `build' for nil:NilClass
#this is in form loading class
def new
#myobject = MyObject.new
#myobject.address = Address.new
end
#Now you can use nested attribute for Address
<%=form_for(#myobject) do |f|%>
<%=f.fields_for :address do |a|%>
Your form fields here
<%end%>
<%end%>
#this is create def
def create
#myobject = MyObject.new(myobject_params)
#myobject.save
end
#in params
def myobject_params
params.require(:myobject).permit(:some, :key,:of, :myobject, :address_attributes[:address, :attribute])
end
#this should work
If my_object has no addresses, then nothing will be rendered. This is default behavior in Rails. One way to get around this is to build one or more empty children in the controller so that at least one set of fields is shown to the user
The Rails guides talk about this in Nested Forms section 9.2
Also, in your MyObject model, i think it should be has_one address. you have belongs_to
class MyObject < ActiveRecord::Base
has_one :address, :autosave => true, dependent: :destroy
accepts_nested_attributes_for :address
end

Simple Search with Rails - Search Results on Separate Page

Im starting out in rails and trying to incorporate a simple search but am only getting so far.
the string looks ok but doesn't seem to execute to the results page. there seems to be a number of issues nil methods, actions missing or routes falling over when I try include restful resources.
I want search on one page (search) and the results to populate to another results page (map).
Both come under the PagesController and are actions within it.
The table is called towns and the user entries and CRUD area it is controlled by the TownsController and has an association with devise User_id.
There is then the pages controller which has search,map,about,contact pages.
class PagesController < ApplicationController
def index
end
def search
#towns = Town.search(params[:search])
end
def page
end
def map
end
end
--------------------------
class Town < ActiveRecord::Base
geocoded_by :name
after_validation :geocode
belongs_to :user
def self.search(search)
if search
search_condition = "%" + search + "%"
where(['townName LIKE ? OR townDescription LIKE ?', search_condition, search_condition])
end
end
-------------------------
views
search.html.erb
<div class="form-group">
<%= form_tag(pages_map_path , method: "get") do %>
<p>
<%= text_field_tag :search, params[:search], class: 'search-text' %>
<%= submit_tag "Search", :name => nil, class: 'btn btn-primary btn-lg'%>
</p>
<% end %>
results --> to map page
map.html.erb
<ul>
<% #towns.each do |town| %>
<li><%= link_to town.name,
:action => 'map', :id => town.id %></li>
<% end %>
</ul>
---------------------------
routes
Rails.application.routes.draw do
devise_for :users
get "pages/search"
get "pages/index"
get "pages/contact"
get "pages/about"
get "pages/map"
get "pages/page"
match ':controller(/:action(/:id))', :via => [:get, :post]
root 'pages#search'
end
Solution:
Column names in search query were incorrect
townName LIKE ? OR townDescription should be = name LIKE ? OR description
updated results page call to:
<ul>
<% #towns.each do |town| %>
<h2><li><%= link_to #name, controller: 'towns', :action => 'show', :id => town.id %></li></h2>
<% end %>
</ul>

gmaps4rails repeating partials for markers

I am having difficulty with gmaps4rails infowindow. I have an app which successfully displays multiple markers using json data stored in activerecord. I created a partial to select additional info to display in the infowindow, but the same data from the first instance of PoliceAlert class is being repeated in each marker:
Controller:
class StaticPagesController < ApplicationController
def main
#police_alerts = PoliceAlert.all
#police_hash = Gmaps4rails.build_markers(#police_alerts) do |police_alert, marker|
marker.lat(police_alert.latitude)
marker.lng(police_alert.longitude)
marker.json({:id => police_alert.id })
marker.picture({
"url" => view_context.image_path('/assets/police.png'),
"width" => 32,
"height" => 37
})
marker.infowindow render_to_string(:partial => '/layouts/police_alerts_infowindow', :locals => { :police_alert => police_alert } )
end
end
Partial:
<% PoliceAlert.find do |police_alert| %>
<%= police_alert.hundred_block_location %>
<br><%= police_alert.event_clearance_description %></br>
<%= police_alert.event_clearance_date %>
<% end %>
How do I get markers to display info for each police_alert? Thanks so much in advance?
Not sure to understand but replace your partial with:
<%= police_alert.hundred_block_location %>
<br/>
<%= police_alert.event_clearance_description %>
<br/>
<%= police_alert.event_clearance_date %>

Rails 3 fields_for different layout for existing records/new records, file uploads

I have a Content model which has one or many Audio files which need to be added by the new/edit form.
What I have did is created the models with this relationship:
class Audio < ActiveRecord::Base
belongs_to :content
has_attached_file :audiofile,
end
class Content < ActiveRecord::Base
...
has_many :audios
accepts_nested_attributes_for :audios, :allow_destroy => true
end
Now in my new Content form I have the following:
<% f.fields_for :audios do |audiof| -%>
<%= f.label :audiofile, 'Audio file:' %>
<%= audiof.file_field :audiofile %>
<% end -%>
What I need it to do is show me the file_field only for a new Audio file and for the existing ones just print me a file size,name and probably a delete button.
I have also created a new record in the controller with:
#content.audios.build
I am using Rails 3.0.3 with Paperclip plugin for upload. Sorry if the question is too nooby.
Thanks.
From my memory, you will be able to access to the instance of the object within the fields_for statement.
Try something like that :
<% f.fields_for :audios do |audiof| -%>
<% if audiof.object.new_record? %>
<%= f.label :audiofile, 'Audio file:' %>
<%= audiof.file_field :audiofile %>
<% else %>
<%= "Filename = #{audiof.object.audiofile.filename}" %>
<%= "url = #{audiof.object.audiofile.url}" %>
<% end %>
<% end -%>
If audiof.object returns nil(In that case, it is not the good name), check by displaying all the public methods <% = raise audiof.public_methods.inspect %>
The object method should return an instance of an Audio class.

Rails 3 Edit Multiple Records in a Single Form

I've been stuck on this problem for a couple of days now.
I've have some success with Railscasts Episode #198, but that one is for Rails 2. There have been some changes in Rails 3 that make it so the code provided in Episode #198 won't work.
The problem lies within the edit_individual.html.erb:
Original Code (provided by Ryan # Railscasts):
<% form_tag update_individual_products_path, :method => :put do %>
<% for product in #products %>
<% fields_for "products[]", product do |f| %>
<h2><%=h product.name %></h2>
<%= render "fields", :f => f %>
<% end %>
<% end %>
<p><%= submit_tag "Submit" %></p>
<% end %>
Modified Code (simply changed fields_for to form_for):
<% form_tag update_individual_products_path, :method => :put do %>
<% for product in #products %>
<% form_for "products[]", product do |f| %>
<h2><%=h product.name %></h2>
<%= render "fields", :f => f %>
<% end %>
<% end %>
<p><%= submit_tag "Submit" %></p>
<% end %>
In the new code, each record is placed within a form of their own, all inside one single form (which is the one I only want).
My question is, how can I get the code provided by Railscasts Episode #198 to work in Rails 3?
Here is a link to the Railscast I mentioned:
http://railscasts.com/episodes/198-edit-multiple-individually
Thank You,
c.allen.rosario
I found the solution. Just need to modify the following line in the code provided by Ryan # Railscasts:
<% fields_for "products[]", product do |f| %>
and change it to:
<%= fields_for "products[]", product do |f| %>
Notice, that the <% has been modified to <%=.
final solution:
<% form_tag update_individual_products_path :method => :put do %>
<% for product in #products %>
<%= fields_for "products[]", product do |f| %>
<h2><%= h product.name %></h2>
<% end %>
<% end %>
<p><%= submit_tag "Submit" %></p>
<% end %>
I was wondering if anyone could explain this solution to me. From what I understand you should only need a <% in front of the fields_for.
c.allen.rosario
The change in Rails 3 from <% fields_for to <%= fields_for is because it was confusing that form_for, form_tag, etc... were using <% form... %> even though they they were outputting html code.
With Rails 3, since they output html code, they use <%=.
Please note that your first line is deprecated:
<% form_tag update_individual_products_path, :method => :put do %>
should be
<%= form_tag update_individual_products_path, :method => :put do %>
Same for all form tags.