Rails Undefined method - ruby-on-rails

I already know there is a lot of undefined method questions, But I can't see whats wrong with mine so I need some help!
heres my form that i have
<% title("Home Page") %>
<h1><i class="fa fa-home"></i> Add Event <small>views/pages/home.html.erb</small></h1>
<div class="row">
<%= simple_form_for Newevent.new do |f| %>
<%= f.input :eventname, required: true %>
<%= f.input :eventdesc %>
<%= f.input :eventdate %>
<%= f.input :eventimage %>
<div class="col s6">
<%= f.input :stubhublink %>
<%= f.input :seatwavelink %>
<%= f.input :viagogolink %>
</div>
<%= f.button :submit %>
<% end %>
</div>
I also have this in the controller
def create
create_params = params[:newevent].permit(:eventname, :eventdesc, :eventdate, :eventimage, :viagogolink, :seatwavelink, :stubhublink)
#newevent = Newevent.new(create_params)
byebug
#newevent.save!
end
and this in the model
class Newevent < ActiveRecord::Base
def params
params.require(:newevent).permit(:eventname, :eventdesc, :eventdate, :eventimage, :viagogolink, :seatwavelink, :stubhublink )
end
end
It was working fine with 3 (which were eventname, eventdate and eventimage) however after adding the other 4 in it now doesn't work. Any ideas?
Sorry heres the error!
NoMethodError in Newevents#new
Showing /Users/samroberts/Desktop/admitme/app/views/newevents/new.html.erb where line #6 raised:
undefined method `eventdesc` for #<Newevent:0x007fcaeee41f68>
Sam

Several problems here buddy:
1. eventdesc Missing
The simple explanation for your error is that your eventdesc attribute is missing from your NewEvent model's table.
Since we don't have your table - or migrations - to observe, I'll have to give you a simple test:
<%= simple_form_for Newevent.new do |f| %>
<%= f.input :eventname, required: true %>
<%= f.input :eventdesc %> #-> remove this line
...
Remove that, refresh the page and see if it works. If the error persists, it may mean another attribute is missing. If it disappears, it means this attribute is missing from your db, and as such you should use rails g migration to create a new one:
$ rails g migration AddEventDesc
#db/migrate/add_event_desc_xxxxxxxx.rb
class AddEventDesc
def change
add_column :new_events, :eventdesc, :string
end
end
2. Params
Part of Rails 4's infrastructure is to use strong params to pass data from your controller to model.
As such, you need the following syntax:
#app/controllers/new_events_controller.rb
class NewEventsController < ApplicationController
def new
#newevent = NewEvent.new
end
def create
#newevent = NewEvent.new new_event_params
#newevent.save
end
private
def new_event_params #-> you can call this whatever you like
params.require(:newevent).permit(:eventname, :eventdesc, :eventdate, :eventimage, :viagogolink, :seatwavelink, :stubhublink )
end
end
You need to keep your strong params function in your controller, not your model.
3. Model Name
Finally, this won't do much for you directly, but in the long run will help you massively; your model name.
Your model is NewEvent.
If this is what you want to call it, that is good. However, I have found the best way forward with model names is to keep them simple, preferably to one word.
I'd strongly recommend calling your model Event, so you can call #event = Event.new etc -- it just flows better.

Related

Getting an 'undefined method' error when trying to generate simple_form

I'm just trying to get some practice in with rails and have started my first project. I am creating a simple project where personal trainers can register profiles and look for work at gyms.
However when trying to navigate to the new personal trainer page this error pops up:
undefined method `pts_path' for #<#<Class:0x5d14ef8>:0x5690b68>
My personal trainer controller looks like this:
class PersonaltrainersController < ApplicationController
def index
#PT = Pt.all
end
def new
#PT = Pt.new
end
def show
end
def create
end
def contact
end
def edit
end
end
Under the routes file I have:
Rails.application.routes.draw do
resources :personaltrainers
root 'personaltrainers#index'
end
My simple_form looks like:
<%= simple_form_for #PT do |form| %>
<%= form.input :name %>
<%= form.input :age %>
<%= form.input :sex %>
<%= form.input :experience %>
<% end %>
personaltrainers_path GET /personaltrainers(.:format) personaltrainers#index
POST /personaltrainers(.:format) personaltrainers#create
new_personaltrainer_path GET /personaltrainers/new(.:format) personaltrainers#new
edit_personaltrainer_path GET /personaltrainers/:id/edit(.:format) personaltrainers#edit
personaltrainer_path GET /personaltrainers/:id(.:format) personaltrainers#show
PATCH /personaltrainers/:id(.:format) personaltrainers#update
PUT /personaltrainers/:id(.:format) personaltrainers#update
DELETE /personaltrainers/:id(.:format) personaltrainers#destroy
root_path GET / personaltrainers#index
Any help would be greatly appreciated.
Change your form code to:
<%= simple_form_for #PT, url: personaltrainers_path do |form| %>
<%= form.input :name %>
<%= form.input :age %>
<%= form.input :sex %>
<%= form.input :experience %>
<% end %>
undefined method pts_path' raised when simple_form_for trying to make a url from the model(pts it is a pluralized form of the pt model), but your routes have another resource name personaltrainers. All that you need, it's pass explicit url to the form helper, in this case it should be personaltrainers_path according your routes file.
You index and new method should be:
def index
#PT = Personaltrainer.all
end
def new
#PT = Personaltrainer.new
end
Btw, we (ruby devs) have a convention to use small case variable names, underscore in case of more_than_one_word. We use ALL_CAPS for constants.

Ruby on Rails controller syntax

I am new to Rails, and just working my way through my first solo project, but I seem to be running into a syntax error with a constant not being initialized (Ive gotten several of these, but each seems to have a different cause.....not quite sure how i keep getting the same error with different causes :)):
uninitialized constant DatastringsController::Datastrings
DatastringsController:
class DatastringsController < ApplicationController
def new
end
def create
#datastrings = Datastrings.new(datastrings_params) #ERROR returned on this line
#datastrings.save
redirect_to #datastrings
end
def show
#datastrings = Datastrings.find(params[:id])
end
private
def datastrings_params
params.require(:datastrings).permit(:title, :text)
end
end
I believe my form is correct:
<%= form_for :datastrings, url: datastrings_path do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
The main problem you have is here:
<%= form_for :datastrings, url: datastrings_path do |f| %>
form_for really should be populated with an ActiveRecord object, as this allows Rails to build the relative paths it requires correctly.
Although I don't know why this is the case, your current setup is basically trying to render DatastringsController::Datastrings -- primarily because you've not set up your form_for correctly
--
Fix
If you want to create a datastring object, I'd follow convention and do this:
#config/routes.rb
resources :datastrings
#app/controllers/datastrings_controller.rb
Class DatastringsController < ApplicationController
def new
#datastring = Datastring.new
end
def create
#datastring = Datastring.new(datastring_params)
#datastring.save
end
private
def datastring_params
params.require(:datastring).permit(:title, :text)
end
end
#app/views/datastrings/new.html.erb
<%= form_for #datastring do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
--
YOU ALSO NEED TO NAME YOUR MODELS IN SINGULAR
Looking at it now, it seems that your main issue is likely that you've named your model as a plural.
The reason this will be bad is that when you load Rails, it will load all your models, and consequently, allow you to call them by referencing their class name. If a model is plural, I don't think it will load it correctly, causing the error you've highlighted
If you name your model to the following, it should be better:
#app/models/datastring.rb
Class Datastring < ActiveRecord::Base
end

In ruby on rails 4, how do I set an attribute in the forms_for helper that is not associated with a model?

I want to be able to access :to_whom text value via params[:to_whom] in the controller. To_whom does not exist in a model.
I get the sensible error:
'undefined method `to_whom' for Conversation'
How can I add an arbitrary attribute to pass back to the controller in rails?
Also, in my view I did Message.new and Conversation.new which is incredibly ugly. I initially set #conversation = Conversation.new in the controller, however I found I had to recreate those variables in the second controller method anyways, which makes sense (after I hit the submit button). Thus instead of setting #message, #conversation in the new method, I removed all the lines from new and did the .new syntax in the view. Is there a more elegant way of writing this code so it isn't so hacky feeling?
CONTROLLER:
class ConversationsController < ApplicationController
attr_accessor :conversation, :user, :to_whom
# this is the method that generates the below view
def new
end
def create
...
end
end
VIEW:
<%= form_for([current_user, Conversation.new]) do |c| %>
<%= c.label :to_whom %>
<%= c.text_field :to_whom %>
<%= c.label :subject %>
<%= c.text_field :subject %>
<%= form_for(Message.new) do |m| %>
<%= m.label :message %>
<%= m.text_field :text %>
<div class="actions">
<%= submit_tag "send" %>
</div>
<% end %>
<% end %>
Virtual Attributes
Your attr_accessor belongs in your model (not your controller). Currently, you have it stored in your controller, which will do nothing at the model-level:
#app/models/conversation.rb
Class Conversation < ActiveRecord::Base
attr_accessor :conversation, :user, :to_whom
end
#app/controllers/conversations_controller.rb
# remove attr_accessor
You have to remember that since Ruby is object-orientated, all the data objects you get are from the model. This means if you call #conversation = Conversation.new, the attributes of that model are actually created in the conversation model
Normally, the model will set the attributes in accordance with your database columns. If you don't have a database column present, you need to create the relevant getter / setter methods using the attr_accessor module
m.text_field :to_whom is just a helper to build an html input tag. You could write your own in raw html, filling in the blanks with erb tags, or you could use other helpers, such as text_field_tag:
text_field_tag "to_whom", params[:to_whom]
I think you need to use fields_for helper, It should be something like below,
= c.fields_for :message do

Why is this rails simple form not working?

I am making a rails application. After a user has registered (I have already created user registration with devise), they can fill out this form that will contain their profile information. I have done this several times, and i can't find what is wrong. Here is the model:
class Information < ActiveRecord::Base
belongs_to :user
end
Here is the controller:
class InformationsController < ApplicationController
def new
#information = Information.new
end
def create
#information = Information.create(params[:information])
redirect_to student_path
end
def index
end
end
And here is the view for the new action.
<div class="span6 offset3 text-center">
<h1>Edit your information</h1>
<%= simple_form_for #information do |f| %>
<%= f.input :skills %>
<%= f.input :looking_for, :label => 'What help do you need?' %>
<%= f.input :my_idea %>
<%= submit_tag "Save", :class => "btn btn-primary btn-large" %>
<% end %>
</div>
Here is the line in the routes file:
resources :informations
I get the following errors which make no sense to me:
undefined method `information_index_path' for #<#:0x007f9c00c7b3e0>
Does anyone know how to fix this? Thanks.
UPDATE:
When I did rake routes, For informations#create, which is what the form should be going to, it has a blank path. There is also informations#index, which is what I guess its going to now. How do I get it to go to informations#create if the path is blank?
Please try yanking out the comments (# signs) in lines 6 and 9 of your view. They might be messing up the ERB processing.
Can you try informations_path? See here.
The problem was with naming the resource information. As information is the same plural as it is singular, it was confusing rails. I renamed the model description and the controller descriptions_controller, and it worked.

Rails 3 - Create View to Insert Multiple Records

I have what seems like a simple query. I need to create a view that will accept multiple records based on a single model. In my case the model is Project, which has 1 foreign key (person) and 2 fields time, role. I need to create a view (form) to insert 5 roles.
<%= form_for(#project) do |f| %>
<% 5.times do |index|%>
<div class="field">
<%= f.label :position %><br />
<%= f.text_field "fields[#{index}][stime]" %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I get an error message: undefined method `fields[0][stime]'
I do not think the railscasts for nested models is what I need.
How would I go about creating this?
EDIT: The Project model code is below:
class Project < ActiveRecord::Base
belongs_to :person
attr_accessible :role, :stime
end
The Projects_Controller code for the new method is below:
def new
#project = Project.new
end
I see you're planning to make some 1-to-many relationship (Product has_many :roles).
Here's some advices.
First, take a look at the accepts_nested_attributes_for method. You need to add it to your model to be able to perform mass-create.
Second, fields_for is what you need to design nested forms.
I'll give you some example of mass-creating for a simple Product has_many :line_items case:
<%= form_for #product do |f| %>
<%= f.fields_for :line_items, [LineItem.new]*5 do |li_fields| %>
<%= li_fields.text_field :quantity %>
<%= li_fields.text_field :price %>
<br>
<% end %>
<%= f.submit "Create line items" %>
<% end %>
All you need is to write in you controller something like:
#product.update_attributes params[:product]
and 5 line_items will be created at once.
Don't forget to white-list association_attributes (see params in your logs to see it). But I think if you get the mass-assignment error you'll do it anyway :)
I hope it helps.

Resources