Rails edit form not showing nested item - ruby-on-rails

I got a form that have a nested link. The problem that the link field is empty on edit.
Here is my form:
<h1>Editing kategori</h1>
<%= simple_form_for(#konkurrancer, :url => {:action => 'update', :id => #konkurrancer.id }) do |f| %>
<%= f.simple_fields_for :link_attributes do |d| %>
<%= d.input :link, :label => 'Tracking url', :style => 'width:500;' %>
<% end %>
<%= f.button :submit, :value => 'Edit konkurrence' %>
<% end %>
<%= link_to 'Show', admin_konkurrancer_path %> |
<%= link_to 'Back', admin_konkurrancer_path %>
My konkurrencer model:
has_one :link
My link model:
class Link < ActiveRecord::Base
belongs_to :konkurrancer
accepts_nested_attributes_for :konkurrancer
end
My konkurrancer edit action:
def edit
#konkurrancer = Konkurrancer.find(params[:id])
#konkurrancer.link_attributes.build
end

1) Remove from your Link model
accepts_nested_attributes_for :konkurrancer
and add to your Konkurrancer model
accepts_nested_attributes_for :link
2) In controller edit action remove
#konkurrancer.link_attributes.build
and in controller new action add
#konkurrances.build_link
3) In the view file replace
<%= f.simple_fields_for :link_attributes do |d| %>
with
<%= f.simple_fields_for :link do |d| %>

Related

edit associated model by input form?

Order has_many jobs
Job belongs to order
And I want to edit attributes of #job.order:
<% order = #job.order %>
<%= simple_form_for [#job, order],
url: job_path(#job),
method: :put,
remote: true do |f| %>
<%= f.input :order_status, input_html: {class: 'form-control'} %>
(...)
<% end %>
any way to do it by just using input in simple form?
in job.rb
accepts_nested_attributes_for :order
in form.html.erb
simple_form_for #job do |f|
f.simple_fields_for #job.order do |order_form|
order_form.input :status
end
end
in jobs_controller.rb
params.require(:job).permit(:something, :something_else, :order_attributes => [:status])
You can use the excellent Cocoon gem https://github.com/nathanvda/cocoon to manage nested relationships, including the ability to easily add new nested relationships.
class Job < ActiveRecord::Base
has_many :orders
accepts_nested_attributes_for :orders, reject_if: :all_blank, allow_destroy: true
end
class Order < ActiveRecord::Base
belongs_to :job
end
Note the pluralization.
_form.html.erb*
<%= form_for #job do |f| %>
<%= f.label :job_name %>
<%= f.text_field :name %>
<div id='order'>
<%= f.fields_for :orders do |order| %>
<%= render 'order_fields', f: order %>
<% end %>
<div class='links'>
<%= link_to_add_association 'add order', f, :orders %>
</div>
<%= f.submit %>
<% end %>
_order_fields.html.erb partial
<div class='nested-fields'>
<%= f.label :order_name %>
<%= f.text_field :order_name %>
</div>
<%= link_to_remove_association "remove order", f %>

nested forms and cocoon. undefined method `label' for nil:NilClass

Hi all. When I open /courses/new (or /courses/some_id/edit), browser returns this error:
Showing /app/views/dashboard/courses/_price.html.erb where line #1 raised:
undefined method `label' for nil:NilClass
Here are codes, _form.html.erb:
<%= simple_form_for [:dashboard, #course], html: { multipart: true } do |f| %>
//////
<%= f.fields_for :prices do |p|%>
<%= render 'price', :f => 'prices' %>
<% end %>
<%= link_to_add_association 'Add', f, :prices %>
////////
_price.html.erb:
<%= p.label :price %>
<%= p.text_field :price %>
<%= p.label :desc %>
<%= p.text_field :description %>
<%= link_to_remove_association "remove", f %>
Models:
class Price < ActiveRecord::Base
belongs_to :course
end
class Course < ActiveRecord::Base
has_many :prices
accepts_nested_attributes_for :prices, :reject_if => :all_blank, :allow_destroy => true
end
How resolve this error? And why it has arisen?
You are using simple_form_for,so i guess this line
<%= f.fields_for :prices do |p|%>
should be
<%= f.simple_fields_for :prices do |p|%>
Have a look at the Git for more Info.
In your _price.html.erb partial view, your are using a form builder that does not exists (is nil) because you did not pass it as argument:
# _price.html.erb
<%= p.label :price %>
#^ the variable `p` is the form builder here
To solve this problem, you have to pass the form builder to the partial view, like this:
<%= f.fields_for :prices do |p| %>
<%= render 'price', :f => 'prices', p: p %>
#^^^^ We pass the variable `p` (form builder) to the partial
<% end %>
Hope this helps!

rails: mass-assign error caused by updating child (Post) from parent (Topic) controller (edit view)

I am trying to edit a Topic which has many Posts.
Edit page for a Topic has Topic's name and Post's content that can be edited.
The mass-assignment error occurs in topics_controller.rb, update method, post.update_attributes(params[:post]).
How do I avoid mass-assignment error.
topic.rb
class Topic < ActiveRecord::Base
has_many :posts, :dependent => :destroy
belongs_to :forum
accepts_nested_attributes_for :posts, :allow_destroy => true
attr_accessible :name, :last_post_id, :posts_attributes
end
post.rb
class Post < ActiveRecord::Base
belongs_to :topic
attr_accessible :content
end
topics_controller.rb
def update
#topic = Topic.find(params[:id])
post = #topic.posts.first
if #topic.update_attributes(params[:topic]) && post.update_attributes(params[:post])
topic = Topic.find(#post.topic_id)
flash[:success] = "Success!"
redirect_to topic_posts_path(topic)
else
render 'edit'
end
end
views/topics/edit.html.erb
<%= form_for #topic do |f| %>
<!-- render 'shared/error_messages_topic' -->
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.fields_for #topic.posts.first do |post| %>
<%= render :partial => "posts/form", :locals => {:f => post} %>
<% end %>
<%= f.submit "Edit", class: "btn btn-large btn-primary" %>
<% end %>
views/posts/_form.html.erb
<%= f.label :content %>
<%= f.text_area :content %>
In update method you don't have to update attributes of both the models instead of if #topic.update_attributes(params[:topic]) && post.update_attributes(params[:post]) it should this only if #topic.update_attributes(params[:topic]) it will update the posts automatically.
And change your view from this <%= f.fields_for #topic.posts.first do |post| %> to <%= f.fields_for :posts, #topic.posts.first do |post| %> it will work fine.
For more information read this http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for

undefined method `my_teas_path' for #<#<Class:0xa8930c8>:0xa578cf8>

My current goal in my first rails project is to have a button that will create a #my_tea using the attributes of a #tea (show page). This is the error I am getting:
'undefined method `my_teas_path' for #<#:0xa578cf8>
I have tried having the form in a _new partial inside my_teas/ and inside teas/_add_tea both have given me the same error. Anyway here is my code as it stands.
View:
<%= form_for([#user, #my_tea]) do |f| %>
<%= f.hidden_field :name, :value => #tea.name %>
<%= f.hidden_field :tea_type, :value => #tea.tea_type %>
<%= f.hidden_field :store, :value => #tea.store %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= fields_for [#user, #tea_relationship] do |r| %>
<%= r.hidden_field :tea_id, :value => #tea.id %>
<% end %>
<%= f.submit "Add Tea", class: "btn btn-large btn-primary" %>
<% end %>
my_tea controller
def new
#my_tea = MyTea.new
end
def show
#my_tea = MyTea.find(params[:id])
end
def create
#my_tea = MyTea.new(params[:my_tea])
if #my_tea.save
flash[:success] = "Tea added to your teas!"
else
redirect_to user_path
end
end
Teas controller:
def show
#tea = Tea.find(params[:id])
#my_tea = MyTea.new
#tea_relationship = TeaRelationship.new
end
Routes
resources :users do
resources :my_teas
end
resources :teas
Models:
class User < ActiveRecord::Base
has_many :my_teas, :dependent => :destroy
has_many :tea_relationships, :dependent => :destroy
class MyTea < ActiveRecord::Base
belongs_to :user
class TeaRelationship < ActiveRecord::Base
belongs_to :user, class_name: "User"
end
Tea model doesn't belong to anything.
Please help rails community your my only hope :p
Update
changing my form to this
<%= form_for([#user, #my_tea]) do |f| %>
<%= f.hidden_field :name, :value => #tea.name %>
<%= f.hidden_field :tea_type, :value => #tea.tea_type %>
<%= f.hidden_field :store, :value => #tea.store %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= fields_for #tea_relationship do |r| %>
<%= r.hidden_field :tea_id, :value => #tea.id %>
<% end %>
<%= f.submit "Add Tea", class: "btn btn-large btn-primary" %>
<% end %>
it works and the #my_tea submits but the #tea_relationship doesn't.
So by the look of things and glimpsing through, it seems like you are trying to do some nested forms. It also appears like you have a many-to-many relationship( tea.rb <=> tea_relationship.rb <=> my_tea.rb) Make sure your Models are set up correctly.
Many to Many
I am not sure why you are trying to do [#user, #my_tea]
Nested Forms
Should be more in the lines of
<%= form_for #my_tea, :url => posting_path do |f| %>
<%= f.simple_fields_for :teas, #my_tea.teas.build do |x| %>
...
<%end%>
...
<%end%>
hope that helps!

Using Formtastic's semantic_fields_for with a has_many association

I am trying to create a nested form using formtastic. I've included my code below but am running into some problems that I've also listed below. Any suggestions? Thanks.
# Home model
class Home < ActiveRecord::Base
has_many :home_members
accepts_nested_attributes_for :home_members, :reject_if => :all_blank, :update_only => true, :allow_destroy => true
end
# Form builder in members/new.html.erb
<%= semantic_form_for #home, :url => home_members_path(#home), :html => { :method => :post }, :remote => true do |f| %>
<%= f.inputs do %>
<%= f.semantic_fields_for :home_members do |h| %>
<%= h.input :name %>
<%= h.input :email %>
<%= h.input :birthday, :as => :string %>
<% end %>
<% end %>
# members_controller's new method; #home is set in a before filter
def new
2.times{ #home.home_members.build }
end
A default user is created when a Home is saved. How do I have the form display only the newly created records and not the existing one?
If #1 isn't possible, how do I make the existing record update? I have update_only set on the accepts_nested_attributes_for, but a new record is still created.
I am doing 2.times{ #home.home_members.build } in the controller action. When I print the size of #home.home_members I get 3 (one already exists) as expected. Why is the form only displaying 2 sets of inputs, one being populated with the existing home_member data?
well to answer question 1) show only the newly created objects
# Form builder in members/new.html.erb
<%= semantic_form_for #home, :url => home_members_path(#home), :html => { :method => :post }, :remote => true do |f| %>
<%= f.inputs do %>
<%= f.semantic_fields_for :home_members do |h| %>
<% if h.object.new_record? %>
<%= h.input :name %>
<%= h.input :email %>
<%= h.input :birthday, :as => :string %>
<% end %>
<% end %>
<% end %>
I've used cocoon with success in the past. https://github.com/nathanvda/formtastic-cocoon

Resources