Associating two models together in Rails 4+ - ruby-on-rails

I have a User model which is working under Devise with no problems (using devise sanitizer to update fields, so no UsersController)
I am working on creating a Quiz model, which belongs_to the User model, and the User model has_one Quiz. In my routes, I have: resources :users, :quizzes (is this supposed to be quizzes or quizs? I know that Rails pluralizes but couldn't seem to find which it'd be in this case).
In my views, I'm trying to open up a modal (which works) and inside have it populated with fields that a User can enter in questions they want (q1 through q5 being the database fields).
Inside the modal content area, I have the code:
<%= form_for #quiz, url: {action: "new"} do |f| %>
<%= f.submit "Create" %>
<% end %>
and I get the error "First argument in form cannot contain nil or be empty"
Inside my quizzes controller, I have defined new as
def new
#quiz = Quiz.new
end
I would greatly appreciate some assistance here! Thank you.

In your WelcomeController action: index add this line to initialized #quiz
def index
#quiz = Quiz.new
end
hope you made a good progress in your project.

shoudn't it be like following
<%= form_for #quiz do |f| %>
<%= f.submit "Create" %>
<% end %>

Related

How to update an existing record?

I have a Books model and it has CRUD operations. In config/routes.rb, I have declared
map.resources :books
My new.html.erb looks like as:
<%= form_for :book, url: books_path do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.submit :Add %>
<% end %>
My create method in controller looks like as:
def create
book = Book.new(authorized_params)
book.save
end
So, when I submit my form from views, request would go to the 'create' method and an record for the book gets created in database. Fair enough. Now, I want to have an edit page for book. So, my edit method in controller look like as:
def edit
#book = Book.find_by(params[:id])
render :new
end
When I go to my edit view, it automatically show the value of title in the text box, which is what I expected.. But when I try to submit the form again(ofcourse after changing the title value) it again creates a new record instead of updating it..
Something basic which I missed out in my reading? I googled about it though but did not find satisfactory answer.
The issue is that you are using the 'new' view where form has the post method. If you will check the generated routes, post will be for create method, that is adding a new record. You will have to create a new view for edit where the form target URL will be edit_book_path(#book) and method will be patch. Patch method will route to 'update' function in your controller where you will call #book.update. I am not writing the exact code, but these directions should help you achieve what you want

Why is this form not working?

I'm making a mailer so that I have a business directory, each business listing has a form and when the form is filled out and submitted it is sent to the relative business email with the lead information.
Here's the mailer folder file:
class Enquiry < ActionMailer::Base
default from: "admin#uk-franchise.co.uk"
attr_accessible :name
def lead(listing)
#listing = listing
mail(to: #listing.leadrecepient, subject: "test")
end
end
Here's the listing controller where I'm calling it:
def lead
listing = Listing.find(params[:id])
Enquiry.lead(listing).deliver
redirect_to listing
end
The view:
<%= form_for #listing, url: lead_listing_path(#listing), method: :put do |listing| %>
<%= listing.text_field :name %>
<%= listing.submit %>
<% end %>
The routes:
resources :listings do
member do
put :lead
end
end
And the error :(
undefined method `name' for #<Listing:0x4d7c6d8>
On the view line:
<%= listing.text_field :name %>
Any help greatly appreciated, mailers are a nightmare!
When you use form_for helper, it actually rely on a model object. Doing this, when you write listing.text_field :name it will actually look for a field name in the listing model. You get that error because your model (connected to a DB table? we would like to see the listing class) doesn't have this field. I can see it in the Enquiry class.
I would say you have to move it in the model, but is hard to say without seeing the Model or knowing for what you need that field...
Show us the model and explain a little better what are you trying to do, so we can help you :)

Strong params and action mailer issues

I have tried to create a mailer using the following code:
routes code
resources :listings do
member do
put :lead
end
end
mailer controller code
def lead(listing)
#listing = listing
mail(to: #listing.leadrecepient, subject: "test")
end
standard controller code
def lead
Enquiry.lead(#listing).deliver
end
view
<%= form_for lead_listing_path(#listing), method: :put do |listing| %>
<%= listing.text_field :name %>
<%= listing.submit %>
<% end %>
In the context of a business directory, I want it so that there is a enquiry form on each listing page that when filled out and submitted, the information is sent to the relative listing email.
The problem however is that when I type into the form and click submit, I get the following error:
param is missing or the value is empty: listing
This seems to be because I have it in the "listing" controller which controls the showing and creation of the business listing itself. I therefore have strong params for a new listing which contains all the new listing variables:
def listing_params
params.require(:listing).permit(:fullname, :jobtitle, :email, :franchisename, :leadrecepint, :shortdescription, :longdescription, :website, :branchcount, :scale, :mininvestment, :investmentrange, :category, :hexbg, :logourl, :facebook, :twitter, :linkedin, :googleplus, :approved)
end
How do I go about fixing this? I'm a beginner if I'm honest, could really do with some help to get this mailer working! Thanks.
Strong params are for when you are submitting new resources or modifications to resources. To protect against people adding extra parameters that may circumvent security or other aspects of your application unexpectedly.
If you are adding an action to an existing resource that the user is authorized to access, which this appears to be, you want to just find the object by ID, and use it. So instead of finding it using the params filtered through listing_params, just find it like this in the controller:
def lead
listing = Listing.find(params[:id])
Enquiry.lead(listing).deliver
redirect_to listing
end
And invoke it using a simple link, instead of this:
<%= form_for lead_listing_path(#listing), method: :put do |listing| %>
<%= listing.text_field :name %>
<%= listing.submit %>
<% end %>
Just use this in your view:
= link_to 'Go!', lead_listing_path(#listing), method: :put
Nothing more to it.

Trying to fire an action in my controller when a selection in a drop down menu is made but getting a no route matches error

I'm building a web interface to accompany a mobile app I'm building. I have a drop down select menu that lists a bunch locations.
On selection of a location I want to make a call to a method in my controller and grab some destinations within the location that was selected (each location has several destinations).
I then would like to render my show template with these results allowing the user to select a destination and make a booking.
This is what I have so far:
My view with a list of resorts:
<%= form_tag :url => { :action => :show } do %>
<%= select_tag :resort , options_for_select(#resorts), :prompt => 'Select Resort', :onchange => 'submit()' %>
<% end %>
Controller:
class HomeController < ApplicationController
def index
#resorts = ["A","B", "C", "D", "E"]
end
def new
end
def edit
end
def create
end
def show
#activities = Parse::Query.new("Activity").tap do |a|
a.eq("resort", params[:resort])
end.get
end
end
Just slightly confused. Using form_for makes more sense to me with CRUD in mind and also because the form is object based.
I'd like to just take the selected resorted and pass it into a method in my controller that goes into a database and grabs a bunch of destinations. I then want to list these destinations on my show page where a user can click and be taken to another page where they can make a booking at that destination.
My above code doesn't work. I have resources :home in my routes file.
However when I try to load my page with the form I get:
No route matches {:action=>"show", :controller=>"home"} missing required keys: [:id]
How do I pull this off?
I went on my lynda account and pulled up a rails essential tutorial which I'll have to use to refresh my memory some time tomorrow but the tutor doesn't cover use of select_tag.
Would appreciate some help here
Thanks for your time
So a few thoughts. Not sure why you are using form_tag and also not sure why you aren't using Rails idiomatic conventions.
Declare a resource in your routes for #resorts, like so:
resources :resorts
Then just use Rails form_for helper like:
<%= form_for #resorts, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
<%= f.select :resort, (insert your other options) %>
<%= f.submit "Create" %>
<% end %>
I have not tested the above code, so play around with it, but that should work.
However, let me save you some headache. Checkout SimpleForm.
For your models, you would want to setup an association between your locations and destinations.
class Location < ActiveRecord::Base
belongs_to :resort # or whatever the relation is
has_many :destinations
end
class Destination < ActiveRecord::Base
belongs_to :location # This assumes there is just a one-to-many relationship between Location and Destination
end
Make sure you have a LocationsController with all the actions.
In this case, your SimpleForm form would look something like this:
<%= simple_form_for #locations do |f| %>
<%= f.input :name %>
<%= f.association :password %>
<%= f.button :submit %>
<% end %>
That approach will make your life much easier. Take a look at the collections methods in Simple Form. Rails can make your life difficult with the built in form helpers.
Hope that helps!
In your routes, add
get '/choose_resort' => 'home#show' #you can name the get whatever
Then in your form...
<%= form_tag choose_resort_path do %>
That being said... you should have your query at a separate endpoint, and redirect to the show page. That should get you moving, methinks.
The show action needs an id of the object you are showing. Change your controller:
class HomeController < ApplicationController
def index
#resorts = [["A",1], ["B",2], ["C",3], ["D",4], ["E",5] ]
end
And your view
<%= select_tag :id , options_for_select(#resorts), :prompt => 'Select Resort', :onchange => 'submit()' %>
That gives your show action the proper resort id. You'll have to adjust that action to find the right activities relevant to the resort.

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.

Resources