Rails: How to hard code field in a form_for - ruby-on-rails

I am working on a Rails project that has nested resources as defined below.
resources :projects do
resources :entries
end
For the entries#new form, I would like to hard code the project_id from the path projects/project_id/entries/new as the project_id field of form_for in the entries' views directory. When I write:
= f.label :project_id
%br
= f.select :project_id, #project
I get the following error:
undefined method `empty?' for #<Project:0x007fa9adc06120>
Any ideas how to send the #project as that field to the form without getting f.select errors? I believe f.select takes a colleciton and so it doesn't like me just giving it a single object as its second parameter.
Thanks for your help!

I guess you have your #entry in the new method of your controller, something like this:
def new
#entry = Entry.new
# etc.
You can use this instead:
def new
#entry = #project.entries.build
# it will set project_id to the #project.id
and in the view:
= f.hidden_field :project_id
If you don't want to initialize with the project_id directly in the view:
= f.hidden_field :project_id, value: #project.id

Related

name error uninitialized constant path in rails

I'm trying to make a form that will post to a database, I'm really struggling at the moment and i'm getting this error.
NameError in AddController#index
uninitialized constant AddController::Newevents
Could you advise what i would need to do?
Heres all the code i have
Form
<%= simple_form_for(#newevent) do |f| %>
<%= f.input :eventname, required: true %>
<%= f.input :eventdate %>
<%= f.input :eventimage %>
<%= f.button :submit %>
<% end %>
controller
class AddController < ApplicationController
def index
#newevent = Newevent.new
end
end
Model
class Newevent < ActiveRecord::Base
def event_params
params.require(:Newevent).permit(:eventname, :eventdate, :eventimage)
end
end
Routes
resources :add
Edit
i now have this error undefined methodnewevents_path'` after changing this
#newevents = Newevent.new
It seems that you miscopied your code here. The error message indicates that your index method actually looks like this
def index
#newevent = Newevents.new
end
Remove the s from the end of Newevent and it should work.
RE: your edit
Your routes declare that you have a resource named add, if you want to show and create your Newevent objects, then you should create a controller for that. Declare resources :newevents in your routes and create a controller to handle it.
You should research RESTful routes, because that's what Rails's resource routing works best with. The form to create a new object should be displayed by the new action and not index.
You should be using create method instead of index if you are using POST http method. index will be called if you are using GET method and it shouldn't be used to post the form data. Refer this link for more information on rails routing.
class AddController < ApplicationController
def create
#newevent = Newevent.new
end
end

simple_form undefined method model_name 3 classes error

So I just Nested some resources that weren't Nested before and since I have been trying to fix all of the path references. The biggest issue I have been having is with the fact that there are 2 nested resources within a larger nested resource like so:
Users->Photos->Comments
On my form, it keeps giving me the following error
undefined method `model_name' for "/users/2/photos/2/comments/new":String
The error page says that the source is around line #1 of the following (my comments/_form partial):
= simple_form_for ([#comment, new_user_photo_comment_path(#user,#photos,#comment)]) do |f|
= f.input :content, label: "Reply to thread"
=f.button :submit, class: "button"
This is my Comments controller:
class CommentsController < ApplicationController
before_action :authenticate_user!
def new
#photo=Photo.find(params[:photo_id])
end
def create
#photo =Photo.find(params[:photo_id])
#comment=Comment.create(params[:comment].permit(:content, :id, :photo_id))
#comment.user_id= current_user.id
#comment.photo_id= #photo.id
#user= User.find_by(params[:id])
if #comment.save
redirect_to user_photo_path(#photo, #user)
else
render 'comments/new'
end
end
end
At first, it is not preferably to nest resources deeper than two times.
You should consider to nest comments within only photos. It`s ok to do like so in routes.rb:
resources :users do
resources :photos
end
resources :photos do
resources :comments
end
And you errors is because
= simple_form_for ([#comment, new_user_photo_comment_path(#user,#photos,#comment)]) do |f|
gives for method simple_form_for as parameters:
1 - model Comment
2 - String /users/2/photos/2/comments/new
to set proper path (form action) form builders need models as all arguments.
Maybe something like
= simple_form_for ([#user,#photos,#comment]) do |f|
should work

Undefined method *_path when trying to use form_for

Category controller:
def new
#cat = Category.new
respond_to do |format|
format.html
end
end
View:
%p Add new category:
~form_for(#cat) do |f|
%div.field
~f.label :name
~f.text_field :name
%div.field
~f.label :description
~f.text_area :description
%div.field
~f.submit
Routes:
resources :category
When I try to load category/new in the browser I get:
undefined method `categories_path' for #<#<Class:0x10d9c9ee8>:0x10d9b0768>
Extracted source (around line #3):
1: %h1 Category#new
2: %p Add new category:
3: ~form_for(#cat) do |f|
4: %div.field
5: ~f.label :name
Any ideas why my form isn't showing?
Also, on my category/index page, where I want to show all categories, under the list of categories I'm getting #<Category:0x10d736b40>. Can I get rid of that somehow?
The route should be
resources :categories
not
resources :category
A bit long for a comment so I've added the following as an answer instead.
If you want a singular resource you need to do:
resource :category
Which will generate only 6 routes (no index):
GET /category/new new
POST /category create
GET /category show
GET /category/edit edit
PUT /category update
DELETE /category destroy
But your controller will still be plural, unless you do the following:
resource :category, controller: :category

undefined method ..._index_path Ruby on Rails

I am trying to get a basic form to work and am struggling because I keep getting the error
undefined method `profiles_index_path' for #<#<Class:0x4fe1ba8>:0x4fccda0>
I have checked through and can't seem to work out where I am going wrong.
In my view (new.html.erb) I have:
<%= form_for #profile do |f| %>
<%= f.text_field :name %>
<%= f.text_field :city %>
<%= f.text_field :country %>
<%= f.text_field :about %>
<%= f.submit "Create Profile" %>
<% end %>
In my profiles controller I have:
class ProfilesController < ApplicationController
def new
#title = "New Profile"
#profile = Profiles.new
end
def create
#user = current_user
#profile = #user.profiles.new(params[:profile])
if #profile.save
redirect_to profile_path, :notice => "Welcome to your new profile!"
else
render "profiles#new"
end
end
def edit
#user = current_user
#profile = #user.profiles.find(params[:id])
end
def update
#title = "Update Profile"
#user = current_user
#profile = #user.profiles.find(params[:id])
if #profile.update_attributes(params[:profile])
redirect_to profile_path
else
render action: "edit"
end
end
def index
#user = current_user
#profile = #user.profiles.all
#title = "Profile"
end
end
And finally in my profiles model I have
class Profiles < ActiveRecord::Base
belongs_to :user
end
Any help people can offer really would be much appreciated because I am stumped. :)
Sorry forgot to include routes:
controller :profiles do
get "newprofile" => "profiles#new"
get "updateprofile" => "profiles#update"
get "profile" => "profiles#home"
end
resources :profiles, :controller => 'profiles'
The problem is indeed the way you've pluralized your model name. Don't do that. It should be a Profile, not a Profiles. There my be some work around to allow you to use a plural model name, but the answer is to stick to Rails convention rather than fighting the framework. Rename your model to Profile and the url_for helpers will understand how to correctly turn a new Profile object into a /profiles URL.
If you run "rake routes" command, do "profiles_index" appear in your routes? Usually for the index page of a model, the work 'index' is left out so the route is profiles_path
You error probably comes from a view where you've used profiles_index_path instead of profiles_path
I think it's failing due to the convention not being followed with your model name.
So I think you're problem is mostly around that you aren't following the convention on the model name, which would classically be singular, since each instance represents one profile. I think the form_for helper is trying to figure out what to do with it and failing as a result. So you have two options to try and resolve. Refactor the model name to singular (I'm not clear exacly how difficult that would be) or pass the :url paramater to form_for so it knows where to post to.
<% form_for #profile, :url => path_to_create_action do |f| %>
more information here:
I'm working with Rails 5 and I got the same error and it was specific using the word Media as my model and RoR used Medium as the plural so I got different routes when executing rake routes.
What I did to fix it was:
Delete the model I just have created.
rails d scaffold Media
Edit config/initializers/inflections.rb with:
ActiveSupport::Inflector.inflections(:en) do |inflect|
# Here you can put the singular and plural form you expect
inflect.irregular 'media', 'medias'
end
Now execute the scaffold again:
rails g scaffold Media
Now you must have everything in the way you expected. Because you have overwritten the Pluralizations and Singularizations (Inflections) in Ruby on Rails.
I hope it could be useful.
Have you tried to replace your form_for tag with the following?
<%= form_for #profile, :as => :post do |f| %>
It looks like it's trying to treat it as a GET request to "/profile". And, since it is not finding the index action, it craps out. I think forcing it to do a POST will fix this issue.

form for nested resource

I have gone through tons of the form_for nested resource questions and can't get any of the solutions to work for me. I figured its time to ask a personalized question.
I have two models, jobs and questions, jobs has_many questions and questions belong_to jobs.
I used scaffolding to create the controllers and models then nested the resources in the routes.rb.
root :to => "pages#home"
resources :jobs do
resources :questions
end
get "pages/home"
get "pages/about"
get "pages/contact"
class Job < ActiveRecord::Base
has_many :questions
end
class Question < ActiveRecord::Base
belongs_to :job
end
Right now I am trying to access '/jobs/1/questions/new' and keep getting the
NoMethodError in Questions#new
I started with the error No route matches {:controller=>"questions"} when the code was
<%= form_for(#question) do |f| %>
I know this is wrong, so I started to try other combos and none of them worked.
I've tried
<%= form_for([#job.questions.build ]) do |f| %>
that
<%= form_for([#job, #job.questions.build ]) do |f| %>
that
<%= form_for(#job, #question) do |f| %>
Among a bunch of other combinations and that are not working.
Here is a link to my rake routes : git clone https://gist.github.com/1032734
Any help is appreciated and let me know if you need more info, thanks.
I just pass the URL as an extra option:
<%= form_for(#question, :url => job_questions_path(#job)) do %>
EDIT:
Also try:
form_for([#job, #question])
This is how I solved mine :)
In your questions/_form.html.erb
<%= form_for [#job, #question] do %>
For this to work, you need the job's id. You'll pass it as follows:
In the questions_controller.rb
def new
#job = Job.find(params[job_id])
#question = #job.questions.build
end
Build(.build) is similar to using new(.new) in the code above, with differences only in older versions of rails; rails 2 down.
Now for the create action (still in questions_controller.rb)
def create
#job = Job.find(params[:job_id])
#question = #job.questions.build(question_params)
end
If you only use these, the job_id and user_id field in the question model will be empty. To add the ids, do this:
In your questions_controller.rb add job_id to job_params like so:
def question_params
params.require(:question).permit(:ahaa, :ohoo, :job_id)
end
Then to pass the user's id (if you are using Devise), do:
def create
#job = Job.find(params[:job_id])
#question = #job.questions.build(question_params)
#question.user_id = current_user.id
end

Resources