i'm trying to render a form but it's throwing an error and I can't find a reason for it.
controller
def new
#student = Student.find(params[:student_id])
#learning_instrument = LearningInstrument.new
end
def create
#student = Student.find(params[:student_id])
#learning_instrument = LearningInstrument.new(learning_instrument_params)
#learning_instrument.student = #student
if #learning_instrument.save
redirect_to student_path(#student)
else
render :new
end
end
private
def learning_instrument_params
params.require(:learning_instrument).permit(:level, :student_id, :instrument_id)
end
this is my form
<%= simple_form_for(#student, #learning_instrument) do |f| %>
<%= f.error_notification %>
<%= f.input :level %>
<%= f.association :instrument, collection: Instrument.all %>
<%= f.hidden_field :student, value: #student %>
<%= f.button :submit %>
<% end %>
I'm getting "can't write unknown attribute builder". I've done stuff like this some times and it worked but this time I can't get it to work
Thanks
can't write unknown attribute builder
This is because of this line <%= simple_form_for(#student, #learning_instrument) do |f| %> .You have to define simple_form_for for nested resources like below
<%= simple_form_for [#student, #learning_instrument] do |f| %>
Related
I am currently doing a CRUD, i am now in part of create method but I'm encountering when I load the new method(this is where my form is) NameError in Products#new
Question: Is my products_create_path correct? This is the action after I send the form into create method
New file
Add New Item
<%= form_for :product, url: products_create_path do |f| %>
<p>
<%= f.label :Name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :Size %><br>
<%= f.text_area :description %>
</p>
<p>
<%= f.label :Price %><br>
<%= f.text_field :price %>
</p>x
<p>
<%= f.submit :Submit %>
</p>
<% end %>
<%= link_to 'BACK', products_path %>
Routes
Rails.application.routes.draw do
resources :products
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Controller
class ProductsController < ApplicationController
def index
#product = Product.all.order('created_at DESC')
end
def show
#post = Product.find(params[:id])
end
def new
#product = Product.new
end
def create
#post = Product.new(post_params)
if #post.save
redirect_to (products_path)
else
redirect_to('new')
end
end
private
def post_params
params.require(:product).permit(:name, :size, :price)
end
end
You don't need to give url in form_for tag. Rails internally redirect to path depends on in presence of id value.
Change form_for tag to this:
<%= form_for #product do |f| %>
So in your form_for tag, object (#product) has value for id field, then rails will submit the form to update routes else it will submit the form to create routes.
In your form change :description to :size
and change
<%= form_for :product, url: products_create_path do |f| %>
to
<%= form_for #product do |f| %>
products_create_path is not correct and you don't need it either. Your form should be <%= form_for(#product) do |f| %>
It should be:
<%= form_for :product, url: products_path do |f| %>
You can check your routes by using this command:
rake routes
Or find more information from here.
Hope I can help.
change your form_tag to
<%= form_for #post, :url => new_product_path do |f| %>
or
<%= form_for #product do |f| %>
I have albums and pictures where albums hasmany pictures
This is my routes.rb
resources :albums do
resources :photos
end
Instead of photos_path my path is album_photos_path
In my photos/new.html.erb I'm getting this error:
undefined method photos_path' for #<#<Class:0x5232b40>:0x3cd55a0>
How I can do to instead of photos_path simple form write album_photos_path ?
My new.html.erb
<%= simple_form_for([#album, #photo]) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :title %>
<%= f.input :description %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
You can specify url in your form. Like this:
<%= simple_form_for #photo, url: album_photos_path do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :title %>
<%= f.input :description %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
But your code should also work. In your new action did you initialize both #album and #photo, something like:
def new
#album = Album.find params[:album_id]
#photo = #album.pictures.build
end
P.S above code is just a sample code and if both variables(#album and #photo) are initialized properly then rails will automatically generate correct url.
You need to set the parent resource.
class PhotosController < ApplicationController
before_action :set_album
# GET /albums/1/photos/new
def new
#photo = #album.photos.new
end
# POST /albums/1/photos
def create
#photo = #album.photos.new(photo_params)
# ...
end
private
# ...
def set_album
#album = Album.find(params[:album_id])
end
end
The reason rails is trying to call photos_path is that the polymorphic route helpers which turn an array of models into a route helper method compact the array. url_for([nil, Photo.new]) will result in the same result as url_for(Photo.new) - photos_path.
My Tag model has_one :tag_option with some checkboxes. When I'm creating new Tag, it gives a new html form in which all tag_option checkboxes are unchecked. I want to set some of them checked by default. What is the best way to do this?
Controller:
def new
#tag = Tag.new
end
Form:
<%= form_for(#tag) do |f| %>
...
<%= f.fields_for :tag_option do |o| %>
#tag.tag_option['status'] = true # It gives an error
<%= o.check_box :status %>
....
<% end %>
<% end %>
Please have a try with the following.
def new
#tag = Tag.new
#tag_option = #tag.build_tag_option({status: true})
end
FORM
<%= form_for(#tag) do |f| %>
...
<%= f.fields_for :tag_option do |o| %>
<%= o.check_box :status %>
....
<% end %>
<% end %>
I have two hidden_fields, user_id and skill_id
<%= form_for #skill do |s| %>
<%= s.label :image, "Upload your skill" %>
<%= s.hidden_field :user_id, value: current_user.id %>
<%= s.hidden_field :skill_id, value: params[:id] %>
<%= s.file_field :image, multiple: true %>
<% end %>
In my controller I have this:
def reviews
#skill = Skill.new
end
I'm able to get the value for skill_id into my database, but I'm not able to get the value from user_id. In my rails console, I see that user_id is being passed through "skill", but doesn't show in my database.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"5+wxS929uxtt..", "skill"=>{"user_id"=>"7", "skill_id"=>"132", ...
I even checked to see if I'm getting any value with <%= current_user.id %>, which I am.
Maybe someone can guide me to the right path in debugging this issue.
Thanks
<%= form_for #skill do |s| %>
<%= s.label :image, "Upload your skill" %>
<%= s.hidden_field :user_id, value: current_user.id %>
<%= s.hidden_field :skill_id, value: params[:id] %>
<%= s.file_field :image, multiple: true %>
<% end %>
This will go to the create action
So what you really want is to update an existing one since you are passing an existing skills id
def reviews
#skill = Skill.find params[:id]
end
Now your form can use this
<%= form_for #skill do |s| %>
<%= s.label :image, "Upload your skill" %>
<%= s.hidden_field :user_id, value: current_user.id %>
<%= s.file_field :image, multiple: true %>
<% end %>
It is now go to the update action, in your controller.
def update
#skill = Skill.find params[:id]
#skill.update_attributes params[:skill]
redirect_to root_path # redirect to somewhere
end
Try this.
You need a create controller that would look something like this:
def create
#skill = Skill.new(params[:skill])
if #skill.save
# Handle a successful save.
else
render 'new'
end
end
You may want to change the name of the def reviews controller to def new, and also add the new routes to config/routes.rb
I have this controller
class PeopleController < ApplicationController
def new
#person = Person.new
#person.phones.new
end
# this is the action that gets called by the form
def create
render text: person_params.inspect
# #person = Person.new(person_params)
# #person.save
# redirect_to people_path
end
def index
#person = Person.all
end
private
def person_params
params.require(:person).permit(:name, phones_attributes: [ :id, :phone_number ])
end
end
and this view
<%= form_for :person, url: people_path do |f| %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<%= f.fields_for :phones do |f_phone| %>
<div class="field">
<p>
<%= f_phone.label :phone_number %><br />
<%= f_phone.text_field :phone_number %>
</p>
</div>
<% end %>
<p>
<%= f.submit %>
</p>
<% end %>
When I fill out both form fields and hit "Save Person" I only get {"name"=>"foo"} - the phone number seems to vanish.
However, when I change phones_attributes to phones I get {"name"=>"foo", "phones"=>{"phone_number"=>"123"}} (this would however cause problems with the create function.
What's wrong here?
Please note that this question is strongly related to that one: accepts_nested_attributes_for: What am I doing wrong as well as to this posting: https://groups.google.com/forum/#!topic/rubyonrails-talk/4RF_CFChua0
You don't have #phones defined in the controller:
def new
#person = Person.new
#phones = #person.phones.new
end
Finally found the problem. In the view there should be
<%= form_for #person, url: people_path do |f| %>
Instead of
<%= form_for :person, url: people_path do |f| %>
#phron said that already here:
accepts_nested_attributes_for: What am I doing wrong