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!
Related
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 %>
I have this slim syntax:
= form_for(#influencer.relationships.build(followed_id: #influencer.id)) do |f|
div = f.hidden_field :followed_id
= f.submit "Follow", class: "btn btn-large btn-primary"
This is the erb i came up but it doesn't work.
<%= form_for(#influencer.relationships.build(followed_id: #influencer.id)) do |f| %>
<% f.hidden_field :followed_id %>
<%= f.submit "Follow" %>
<% end %>
<%= form_for #influencer.relationships.build(followed_id: #influencer.id) do |f| %>
<%= f.hidden_field :followed_id %>
<%= f.submit "Follow" %>
<% end %>
Conversely, it's bad practice to build an object out of the controller scope. #influencer.relationships.build(followed_id: #influencer.id) should be done inside the controller:
#app/models/influencer.rb
class Influencer < ActiveRecord::Base
has_many :relationships, foreign_key: :follower_id
end
#app/controllers/relationships_controller.rb
class RelationshipsController < ApplicationController
def new
#influencer = Influencer.find params[:influencer_id]
#relationship = #influencer.relationships.build #-> "followed_id" SHOULD be a foreign key in the model. If you have it in the model, you won't need to explicitly define it
end
end
Thus, you'll get:
<%= button_to "Follow", #relationship %>
I have a strong parameter like this
params.require(:survey).permit( option_booleans_attributes: [:id, :survey_id, :topic, :answer])
if I use rails f.input I got parameter like
"option_booleans_attributes"=>{"0"=>{"answer"=>"true", "id"=>"5"}, "1"=>{"answer"=>"false", "id"=>"6"}, "2"=>{"answer"=>"true", "id"=>"7"}}}
but I need to show option_booleans topic and let user fill answer
<% #survey.option_booleans.each do |question| %>
<%= question.topic %><br>
<%= radio_button "option_booleans_attributes[]", "answer[#{question.id}]", "true" %>是
<%= radio_button "option_booleans_attributes[]", "answer[#{question.id}]", "false" %>否<br>
<% end %>
But I don't know how to generate the 0 1 2 in the parameter..
about my survey.rb
class Survey < ActiveRecord::Base
has_many :option_booleans
accepts_nested_attributes_for :option_booleans
belongs_to :member
end
class OptionBoolean < ActiveRecord::Base
belongs_to :survey03
and OptionBoolean have topic:string and answer:boolean
I want to let user see the topic and update the answer
It seems you're missing several parts of your form:
#app/controllers/surveys_controller.rb
def new
#survey = Survey.new
#survey.option_booleans.build #-> creates ActiveRecord Object for your form
end
#app/views/surveys/new.html.erb
<%= form_for #survey do |f| %>
<%= f.fields_for :option_booleans do |option| %>
<% #survey.question_booleans.each do |question| %>
<%= question.topic %>
<%= f.radio_button "answer[#{question.id}]", "true" %>
<%= f.radio_button "answer[#{question.id}]", "false" %>
<% end %>
<% end %>
<% end %>
Although I don't quite understand how your system works
You have a survey with many options, but you're passing new attributes to create new options each time. Surely you'd have option_booleans as a join model, with options as an independent model, and:
#app/models/survery.rb
Class Survey < ActiveRecord::Base
has_many :option_booleans
has_many :options, through: :option_booleans
end
What I use now
<li><% #survey03.option_booleans.each do |question| %>
<%= question.topic %><br>
<%= radio_button "option_booleans_attributes[#{question.id}]", "answer", "true", :required => true %>
<%= radio_button "option_booleans_attributes[#{question.id}]", "answer", "false", :required => true %>
<% end %></li>
and in controller
params[:option_booleans_attributes].each do |option_id, attributes|
if option = OptionBoolean.find_by_id(option_id)
option.update_attributes(attributes)
end
end
and I know if I want to generate index just use
<% #survey.option_booleans.each_with_index do |question, index| %>
<%= question.topic %><br>
<%= radio_button "option_booleans_attributes[#{index}]", "answer[#{question.id}]", "true" %>
<%= radio_button "option_booleans_attributes[#{index}]", "answer[#{question.id}]", "false" %>
<% end %>
try select options like this:
#variable_with_booleans = [true, false]
<%= f.select :param, #variable_with_booleans %>
answer to your latest comment:
I don't sure, but try to edit your form
<%= form_for #question do |f| %>
<%= f.label :topic %>
<% #variable_with_booleans = [true, false] %>
<%= f.select :answer, #variable_with_booleans %>
<%= f.submit %>
<% end %>
and edit your strong params in controller,which contains this action
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
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| %>