I've created a contact form in Rails 4 with this example.
But I want to display this contact form on the main/show page of my application. How can I do this?
routes.rb.
Rails.application.routes.draw do
resources :projects
resources :contacts, only: [:new, :create]
get 'welcome/index'
root 'welcome#index'
end
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
#contact.request = request
if #contact.deliver
flash.now[:error] = nil
else
flash.now[:error] = 'Cannot send message.'
render :new
end
end
end
Thanks.
And easy and clean way would be to create a partial
_contact_form.html.erb (Partials always starts with an underscore)
.container
%h1 Contact
= simple_form_for #contact, :html => {:class => 'form-horizontal' } do |f|
= f.input :name, :required => true
= f.input :email, :required => true
= f.input :message, :as => :text, :required => false, :input_html => {:rows => 10}
.hidden
= f.input :nickname, :hint => 'Leave this field blank!'
.form-actions
= f.button :submit, 'Send message', :class=> "btn btn-primary"
Then, in your index page:
<%= render "contacts/contact_form" %>
and in your controller index action( I don't know if 'welcome/index' is on project's controller or contacts controller)
def index
#your code
#contact = Contact.new
end
Finally, you seem quite new to rails, I'd like to recommend a free Ruby on Rails Tutorial
Related
When I try to edit an instance of my Job model, the attributes I'm trying to update are set to Nil.
I've tried using the regular form_for helper instead of simple_form because I didn't know if simple_form required extra info such as what action and method to use, but it didn't work.
edit.html.erb
<h1>Edit Job:</h1>
<br>
<%= simple_form_for #job do |f| %>
<%= f.input :title, label: "Job title" %>
<%= f.input :description, label: "Description" %>
<%= f.button :submit %>
<% end %>
jobs_controller.rb
def edit
#job = Job.find(params[:id])
end
def update
#job = Job.find(params[:id])
#job.update(title: params[:title], description: params[:description])
if #job.save
redirect_to jobs_path(#job)
else
render "edit"
end
end
routes.rb
resources :candidates
resources :tenants, constraints: { subdomain: 'www' }, except: :index
resources :jobs, path_names: { new: 'add' }
get 'candidates/index'
get 'candidates/new/:id' => 'candidates#new', :as => 'apply'
get 'candidates/single/:id' => 'candidates#single', :as => 'view_candidate'
get 'jobs/single/:id' => 'jobs#single', :as => 'single_job'
get 'add-job' => 'jobs#new'
get 'listings' => 'jobs#listings', :as => 'career_page'
get 'listing/:id' => 'jobs#listing', :as => 'view_job'
get 'welcome/index', constraints: { subdomain: 'www' }
get 'dashboard' => 'tenants#dashboard', as: 'dashboard'
constraints SubdomainConstraint do
devise_for :users, path_names: { edit: 'account' }
root 'tenants#dashboard'
end
root 'welcome#index'
No error, but attributes are Nil, and URL is displayed instead of #job.title in the index view (because its Nil)
I believe the form data are wrapped into key :job in params so attributes for Job need to be whitelisted
def update
#job = Job.find(params[:id])
#job.update(job_params)
if #job.save
redirect_to jobs_path(#job)
else
render "edit"
end
end
Private
def job_params
params.require(:job).permit(:title, :description)
end
I'm trying to make a custom edit form for devise user, but when I submit the form shell throw me this error:
No route matches [POST] "/profile/12/edit"
Here is my form:
= simple_form_for(:user), html: { method: :put }) do |f|
= f.input :email
= f.input :username
= f.input :phone
= f.input :password, autocomplete: "off", required: false
= f.input :password_confirmation, required: false
= f.input :current_password, required: true
= f.button :submit, 'Update'
Here is my profile_controller
class ProfileController < ApplicationController
def show
#client = Client.find(params[:id])
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
redirect_to root_path
end
end
end
And my routes.rb :
Rails.application.routes.draw do
root 'home#index'
devise_for :users
resources :profile
end
What I'm doing wrong?
This is how I would do it:
= simple_form_for #user,
:url => url_for(:action => 'edit', :controller => 'profiles'),
:method => 'put' do |f|
Here you are submitting a PUT (update) request to the edit action of your ProfilesController.
Also notice the difference here between ProfileController and what I wrote ProfilesController. The convention in Rails and as for DHH is that your model names should be singular and your controller plural.
model
class Profile < ActiveRecord::Base
end
controller
class ProfilesController < ApplicationController
end
Replace:
= simple_form_for(:user), html: { method: :put }) do |f|
with:
= simple_form_for #user, method: :put, url: "/profile" do |f|
Some of the mistakes:
if you want to edit an object, provide it, not a mere symbol
the path must be adjusted to point to /profile
method not an html property, it creates a hidden field intercepted by rails in order to know the received post should be understood as a put
we feel like there is a typo: controller should be pluralized
models/lead.rb
class Lead < MailForm::Base
attribute :fullname
def headers
{
:subject => "My Contact Form",
:to => "callumshorty#hotmail.com",
:from => "admin#uk-franchise.co.uk"
}
end
end
controllers/lead_form_controller.rb
class LeadFormController < ApplicationController
def new
#lead = Lead.new
end
def create
#lead = Lead.new(params[:lead_form])
#lead.request = request
#lead.deliver
end
end
routes.rb
resources :lead_form
views/listings/show.html.erb
<%= form_for #lead, :url => url_for(:controller => 'lead_form', :action => 'new') do |lead| %>
<%= lead.text_field :fullname %>
<%= lead.submit %>
<% end %>
The error when trying to access the show page:
First argument in form cannot contain nil or be empty
On line:
<%= form_for #lead, :url => url_for(:controller => 'lead_form', :action => 'new') do |lead| %>
Any help would be super appreciated, can't stand these mailers :(
Your #lead needs to be initialised in the ListingsController#show action, since your lead form is in that view. Try adding #lead = Lead.new in the ListingsController#show method.
I'm trying to add a contact form for my Rails 3.1.3 application using this tutorial. However at the end when I try to load my contact page, I get the error:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
It says it occurs on line 1 of this code block on the new.html.haml page:
= form_for #message, :url => { :action=>"new", :controller=>"contact"} do |form|
%fieldset.fields
.field
= form.label :name
= form.text_field :name
.field
= form.label :email
= form.text_field :email
.field
= form.label :body
= form.text_area :body
%fieldset.actions
= form.submit "Send"
My controller looks like this:
class ContactController < ApplicationController
def new
#message = Message.new
end
def create
#message = Message.new(params[:message])
if #message.valid?
NotificationsMailer.new_message(#message).deliver
redirect_to(root_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :new
end
end
end
Model looks like this:
class Message < ActiveRecord::Base
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :body
validates :name, :email, :body, :presence => true
validates :email, :format => { :with => %r{.+#.+\..+} }, :allow_blank => true
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
Why would I be getting that error and how do I fix it? Thanks!
do you add the routes as mention in the tutorial ?
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
Beside you can just use in ur form as
<%= form_for #message, :url => contact_path do |form| %>
If you are using separate forms for new and edit actions, you can this in new.html.haml
= form_for :message, :url => { :action=>"new", :controller=>"contact"} do |form|
or
= form_for :message, #message, :url => { :action=>"new", :controller=>"contact"} do |form|
I am getting started with rails, so this is a fairly basic question. I am trying to render a login form (authlogic) in the homepage, using this code:
views/home/index.html.haml:
%p
This is the home page...!
- if current_user
- else
= render :template => 'user_sessions/new'
user_sessions_controller:
class UserSessionsController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => :destroy
def new
#user_session = UserSession.new
end
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default user_controls_url
else
render :action => :new
end
end
def destroy
current_user_session.destroy
flash[:notice] = "Logout successful!"
redirect_back_or_default home_url
end
end
views/user_sessions/new.html.haml
= form_for #user_session, :url => {:action => "create"} do |f|
= f.error_messages
%div
= f.label :login
= f.text_field :login
%div
= f.label :password
= f.password_field :password
%div
= f.check_box :remember_me
= f.label :remember_me
%div
= f.submit "Login"
models/user_session.rb
class UserSession < Authlogic::Session::Base
def to_key
new_record? ? nil : [ self.send(self.class.primary_key) ]
end
httponly true
secure true
end
When I visit the homepage, I get:
ActionView::Template::Error (undefined method `model_name' for NilClass:Class):
1: = form_for #user_session, :url => {:action => "create"} do |f|
2: = f.error_messages
3: %div
4: = f.label :login
app/views/user_sessions/new.html.haml:1:in `_app_views_user_sessions_new_html_haml___182031841_97682750'
app/views/home/index.html.haml:6:in `_app_views_home_index_html_haml__679857083_97787190'
What am I doing wrong, and how do I fix it?
Thanks a lot for your help.
In your code, #user_session is being created when you visit the new action that is connected to user_sessions/new; it is not created when you go to the index action.
When you render the user_sessions/new template from the index action, ERB/HAML is looking for an instance of #user_session and cannot find it, hence the error.
So, you could instantiate #user_session like this:
#Note: The <%%> is ERB code (please adjust it for the syntax used in HAML)
<% #user_session = UserSession.new if #user_session.nil? %>
= form_for #user_session, :url => {:action => "create"} do |f|
...
Or, you can also do it in the index action itself, though it would be better to keep it out from the index action and instead do it as above (eg. what if you want to render the template from some other action as well - then you would be duplicating code unnecessarily)