Rails 4, Paperclip and polymorphic association - ruby-on-rails

I have 2 models: News and Uploadedfile
class News < ActiveRecord::Base
has_many :uploadedfiles, as: :parent
attr_accessible :title, :content, :author
end
class Uploadedfile < ActiveRecord::Base
belongs_to :parent, polymorphic: true
has_attached_file :url
attr_accessible :url_file_name, :url_content_type, :url_file_size, :url_updated_at
end
And form:
<%= form_for(#news) do |f| %>
<div class="field">
<%= f.fields_for :uploadedfile, f.uploadedfile.new do |uf| %>
<%= uf.label :url %><br>
<%= uf.file_field :url %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
When i'm submitting form, my table uploadedfile is not changed
where is the problem? thank you!

I think you have nested arribute :uploadedfiles
class News < ActiveRecord::Base
has_many :uploadedfiles, as: :parent
attr_accessible :title, :content, :author, :uploadedfiles_attributes
accept_nested_attributes_for :uploadedfiles
end
And in form :
change:
<%= f.fields_for :uploadedfile, f.uploadedfile.new do |uf| %>
to:
<%= f.fields_for :uploadedfiles, Uploadedfile.new do |uf| %>

I don't think you need polymorphic association here. Here is a more readable way of doing this:
class News < ActiveRecord::Base
has_many :uploadedfiles
attr_accessible :title, :content, :author
accept_nested_attributes_for :uploadedfiles
end
class Uploadedfile < ActiveRecord::Base
belongs_to :news
has_attached_file :url
attr_accessible :url_file_name, :url_content_type, :url_file_size, :url_updated_at
end
*note that I've added accept_nested_attributes_for
And the form:
<%= form_for(#news) do |f| %>
<div class="field">
<%= f.fields_for :uploadedfiles do |uf| %>
<%= uf.label :url %><br>
<%= uf.file_field :url %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

Related

Rails 4.0 nested object forms not rendered

I have two models in my app: "WorkPost" and "Contacts".
WorkPost
class WorkPost < ActiveRecord::Base
has_one :contacts
end
Contacts
class Contacts < ActiveRecord::Base
belongs_to :work_post
end
In my controller's new method I do:
def new
#work_post = WorkPost.new
#work_post.contacts
end
And in view I create form:
<%= form_for(#work_post) do |f| %>
<div class="field">
<%= f.label 'Vacation' %><br>
<%= f.text_field :post_title, :placeholder => 'Vacation here' %>
</div>
<div class="field">
<%= f.label 'Vacation description' %><br>
<%= f.text_area :post_body, :placeholder => 'Vacation description here' %>
</div>
<% f.fields_for :contacts do |cf| %>
<div class="field">
<%= cf.label 'Email' %><br>
<%= cf.text_field :emails, :placeholder => 'Email here' %>
</div>
<% end %>
<div class="actions">
<%= f.submit "Post vacation", :class => 'btn_act' %>
</div>
<% end %>
But it seems like line <% f.fields_for :contacts do |cf| %> doesn't work.
Everything is rendered fine but email field.What I am doing wrong?
The problem is with this line
<% f.fields_for :contacts do |cf| %>
which should be
<%= f.fields_for :contact do |cf| %>
Also, the class name for the model and the association name for has_one/belongs_to should be singular.
#work_post.rb
class WorkPost < ActiveRecord::Base
has_one :contact #should be singular
end
#contact.rb
class Contact < ActiveRecord::Base #should be singular
belongs_to :work_post
end
Also, notice the change :contacts to :contact, as it is a has_one association.
Update:
Also, try the below changes
Include accepts_nested_attributes_for :contact in work_post.rb model
#work_post.rb
class WorkPost < ActiveRecord::Base
has_one :contact
accepts_nested_attributes_for :contact
end
Change the new method to below
def new
#work_post = WorkPost.new
#work_post.build_contact
end

Rails 4 fields_for not displaying field

I have two models that I would like to create with one form. I tried following this railscasts tutorial, but I just can't get the nested fields to display on the form. How can I make these nested fields appear?
Models
class Poll < ActiveRecord::Base
has_many :poll_answers, :dependent => :destroy
accepts_nested_attributes_for :poll_answers, allow_destroy: true
end
class PollAnswer < ActiveRecord::Base
belongs_to :poll
end
Controller
class PollsController < ApplicationController
def new
#poll = Poll.new
2.times { #poll.poll_answers.build }
end
private
def poll_params
params.require(:poll).permit([
:question,
poll_answers_attributes: [:answer]
])
end
end
View
<%= form_for(#poll) do |f| %>
<div class="field">
<%= f.label :question %><br>
<%= f.text_field :question %>
</div>
<% f.fields_for :poll_answers do |pa| %>
<p>Hello
<%= pa.text_field :answer %>
</p>
<% end %>
<%= debug #poll.poll_answers %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You missed an =
<%= f.fields_for :poll_answers do |pa| %>
<p>Hello
<%= pa.text_field :answer %>
</p>
<% end %>

Syntax for select options helper method for second distant has_many through association

How do you correctly fill in the following syntax to create a dropdown select tag with each option being the data of another table?
<%= form_for(#celebrity, :html => { :multipart => true }) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :image %>
<%= f.file_field :image %>
<%= f.label :character %>
<%= f.collection_select(:character, :celebrity_id, #characters, :id, :name) %> #this line is the question
<%= f.submit 'Save' %>
<% end %>
I followed the API documentation here, but it doesn't seem to work.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
class Celebrity < ActiveRecord::Base
has_many :characters, through: :char_celeb_joins
has_many :char_celeb_joins
has_many :universes, through: :characters
end
class Character < ActiveRecord::Base
has_many :universes, through: :univ_char_joins
has_many :univ_char_joins
has_many :celebrities, through: :char_celeb_joins
has_many :char_celeb_joins
end
class Universe < ActiveRecord::Base
has_many :characters, through: :char_univ_joins
has_many :char_univ_joins
has_many :celebrities, through: :characters
end
But I get a
undefined method 'merge' for :name:Symbol
in the browser, when I go to a view that brings up this code.
NoMethodError in Celebrities#edit
The error is due to this line
<%= f.collection_select(:character, :celebrity_id, #characters, :id, :name) %>
When using with form_for,you have to set it like this
<%= f.collection_select(:celebrity_id, #characters, :id, :name) %>
And also your form_for object is #celebrity and you are giving :character as object to collection_select.It should be :celebrity in the collection_select too.Ofcourse you have worry about this when using collection_select without form_for.In your case it would be
<%= collection_select(:celebrity, :celebrity_id, #characters, :id, :name) %>
You can use helper:
Writer this code in any of the helper:
def character_for_select
Character.all.collect { |m| [m.id, m.name] }
end
Update your form
<%= form_for(#celebrity, :html => { :multipart => true }) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :image %>
<%= f.file_field :image %>
<%= f.label :character %>
<%= f.select(:character, character_for_select, :prompt => 'Select character') %>
<%= f.submit 'Save' %>
<% end %>
You will get your answer :)
Have you tried to use options_for_select. In your case, your code should be something like this:
app/helpers...
def options_for_characters( selected=nil )
options = Character.all.map { |c| [d.id, c.name] }
options_for_select( options, selected )
end
app/views...
...
<%= f.select(:character, options_for_characters, :prompt => 'Select character') %>
...

Rails 4: fields_for in fields_for

I am learning RoR and i am trying to find how to set a fields_for in another one with has_one models like this:
class Child < ActiveRecord::Base
belongs_to :father
accepts_nested_attributes_for :father
end
class Father < ActiveRecord::Base
has_one :child
belongs_to :grandfather
accepts_nested_attributes_for :grandfather
end
class Grandfather < ActiveRecord::Base
has_one :father
end
I used Nested Model Form Part 1 on Railscasts to get these:
In children_controller.rb:
def new
#child = Child.new
father=#child.build_father
father.build_grandfather
end
def child_params
params.require(:child).permit(:name, father_attributes:[:name], grandfather_attributes:[:name])
end
And my form:
<%= form_for(#child) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
mother:<br>
<%= f.fields_for :father do |ff| %>
<%= ff.label :name %>
<%= ff.text_field :name %><br>
grand mother:<br>
<%= f.fields_for :grandfather do |fff| %>
<%= fff.label :name %>
<%= fff.text_field :name %>
<% end %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I am trying to retrieve the datas with:
<%= child.father.name %>
<%= child.father.grandfather.name %>
but the grandfather's name won't work.
I cannot find the mistake(s)...anyone to help on this?
Thanks!
Try switching:
<%= f.fields_for :grandfather do |fff| %>
to:
<%= ff.fields_for :grandfather do |fff| %>
And switching:
params.require(:child).permit(:name, father_attributes:[:name], grandfather_attributes:[:name])
To:
params.require(:child).permit(:name, father_attributes:[:name, grandfather_attributes:[:name]])

Rails 3.1 - Editing Attributes in join models?

I'm having real trouble getting my head around editing attributes in has_many through join models. I've set up a very simple app to experiment with; Recipes, Ingredients and Recipe_Ingredients (the join).
Can anyone help with making this work as it should? As it is, it'll pulling through 'qty' from the join model, but not the actual ingredient.
I've put a public repo up that anyone can download to play with: https://github.com/EssentialMusic/Recipes
The models:
class Ingredient < ActiveRecord::Base
attr_accessible :name
has_many :recipe_ingredients, :dependent => :destroy
has_many :recipes, :through => :recipe_ingredients
end
class Recipe < ActiveRecord::Base
attr_accessible :author, :description, :name, :recipe_ingredients_attributes, :ingredients_attributes
has_many :recipe_ingredients, :dependent => :destroy
has_many :ingredients, :through => :recipe_ingredients
accepts_nested_attributes_for :ingredients, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => :true
accepts_nested_attributes_for :recipe_ingredients
end
class RecipeIngredient < ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
attr_accessible :measure, :qty, :special_instructions
end
The form
<%= form_for(#recipe) do |f| %>
<% if #recipe.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#recipe.errors.count, "error") %> prohibited this recipe from being saved:</h2>
<ul>
<% #recipe.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 :author %><br />
<%= f.text_field :author %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div>
<%= f.fields_for :recipe_ingredients do |ri| %>
<%= ri.text_field :qty %> -
<%= ri.fields_for :ingredients do |i| %>
<%= i.text_field :name %><br>
<% end %>
<% end %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Cheers!!
Substitute the ri with f in the second nested fields_for like this:
<%= f.fields_for :recipe_ingredients do |ri| %>
<%= ri.text_field :qty %> -
<%= **f**.fields_for :ingredients do |i| %>
<%= i.text_field :name %><br>
<% end %>
<% end %>

Resources