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.
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| %>
A newby to rails (I am building an app to learn rails) and run in to an issue I can't find a solution to (while following the getting started guide). I have studied the guides and similar questions
This is my code:
class ProjecttypesController < ApplicationController
def index
#projecttypes = Projecttype.all
end
def show
#projecttype = Projecttype.find(params[:id])
end
def new
end
def create
#projecttype = Projecttype.new(projecttype_params)
#projecttype.save
redirect_to #projecttype
end
private
def projecttype_params
params.require(:projecttype).permit(:name, :image, :url)
end
end
The form:
<%= form_for :projecttypes, url: projecttypes_path do |f| %>
<p>
<%= f.label 'Project type' %>
<%= f.text_field :projecttype %>
</p>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :image %>
<%= f.file_field :image %>
</p>
<p>
<%= f.label :url %>
<%= f.url_field :url %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
What am I doing wrong?
Perhaps important... when I use this...
def create
render plain: params[:projecttype].inspect
end
It returns 'nil'.
Thanks for your help
Your code should be like this
def new
#projecttype = Projecttype.new
end
def create
#projecttype = Projecttype.create(projecttype_params)
redirect_to #projecttype
end
and use this for form
<%= form_for #projecttype do |f| %>
In your
controller file
def new
#projecttype = Projecttype.new
end
and then in your form
<%= form_for #projecttype do |f| %>
I want to create a form for "Comments" route which is a member of Article Resources:
resources :articles do
member do
post 'comments'
end
end
I want the comment form to be in Articles#Show page. The problem i got an error:
First argument in form cannot contain nil or be empty
If the for is like this:
<div>
<%= form_for #comm do |c| %>
<%= c.label :Your_comment %>
<%= c.text_area :commBody %>
<%= c.submit 'submit' %>
<% end %>
</div>
So how to do it ?
If this is your controller,
def show
#article = Article.find(params[:id])
end
and you want to create a form for a new Comment related to #article that points to POST /articles/3/comments:
<%= form_for([#article, Comment.new], as: :article, url: comments_article_path(#article)) do |f| %>
<%= f.label :body %>
<%= f.text_area :body %>
<%= f.submit 'Submit' %>
<% end %>
Don't forget to add accepts_nested_attributes_for :comments in the Article model. And also don't forget to setup the whitelisted params in the ArticleController.
Another thing: don't use abbreviations for your variable names. Use #article and #comment, not #art and #comm.
#config/routes.rb
resources :articles do
post :comment, on: :member #-> url.com/articles/:id/comment
end
#app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
def show
#article = Article.find params[:id]
#comment = #article.comments.new
end
end
#app/views/articles/show.html.erb
Comment:
<%= form_for [#article, #comment], url: article_comment_path(#article) do |c| %>
<%= c.label "Your Comment" %>
<%= c.text_area :commBody %>
<%= c.submit %>
<% end %>
I'm trying to make two forms for two different models in the same view.
I have a model named category and a model named post.
Im trying to make a form for categories in the same view i have a form for posts.
The form for posts works fine, but when i'm trying to add the form for categories i get this error:
undefined method `model_name' for Category::ActiveRecord_Relation:Class
category.rb - model
has_many :posts
post.rb - model
has_many :categories
posts_controller
def index
#posts = new.Post
#categories = new.Category
end
def create
#posts = Post.create(post_params)
#posts.save
redirect_to :back
end
def create_cate
#categories = Categroy.create(categories_params)
#categroies.save
redirect_to :back
end
posts view - index.html.erb
<%= form_for(#posts) do |f| %>
<%= f.text_field :title %>
<%= f.text_area :content %>
<%= f.submit %>
<% end %>
<%= form_for(#categories) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
routes.rb
resources :posts
resources :categories
root 'posts#index'
I have tried to search after if, but i can only find solutions for two models, one form.
Thanks in advance. :-)
Since you say its in the index action:
def index
#post = Post.new
#category = Category.new
end
In your view:
<%= form_for(#post) do |f| %>
<%= f.text_field :title %>
<%= f.text_area :content %>
<%= f.submit %>
<% end %>
<%= form_for(#category) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
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