Rails ContactUs model in single pages controller - ruby-on-rails

Hi have simple rails site with no models, its used just for serving static pages.
The site has a Pages controller, but this is only serving up one home page made of partials.
Like such in the app/views/pages/home.html.erb
<%= render 'layouts/about' %>
<%= render 'layouts/services' %>
<%= render 'layouts/rooms' %>
<%= render 'layouts/breakfast' %>
<%= render 'layouts/guestbook' %>
<%= render 'layouts/contact' %>
The home page uses some html5/javascript which autoscrolls the page. So each section is prefaced with # to allow auto scrolling to that section.
<li><a class="home" href="#home">Home</a></li>
<li><a class="services" href="#services">Tarrifs</a></li>
<li><a class="portofolio" href="#portofolio">Rooms</a></li>
<li><a class="breakfast" href="#breakfast">Breakfast</a></li>
<li><a class="contact" href="#contact" >Contact </a></li>
<li><a class="services" href="#services">Blog / Whats On.</a></li>
<li><a class="guestbook" href="#guestbook">Guest Book</a></li>
<li class="description">Take a look.</li>
This all works fine.
Dev site is here
Now my question / issue is : I'd like to add a rails type ContactUS page.
Following various tutorials :
Simple Contact Us
Rails 3 Contact us
They all point to having a message model,ActionMailer, and contact controller, which works if you want to have a separate contact controller.
I'm stuck at trying to figure how I can build a contactUs form but keep it the pages controller to allow the autoscrolling to work as using a contact controller seems to change all the URL routes. I know this probably isn't the Rails way, but any help would be great.
Hope that made sense. Any ideas ?

I would do following:
Add a new model called "Form", app/models/form.rb
class Form
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :message
validates :name, presence: true
validates :email, presence: true, email: true
validates :message, presence: true
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def persisted?
false
end
end
modify your pages_controller:
def new
#form = Form.new
end
def create
#form = Form.new(params[:form])
if #form.valid?
redirect_to root_path, notice: "Thanks!")
else
render "new"
end
end
Add the form html code to your app/views/pages/home.html.erb
<%= form_for #form do |f| %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.label :message %>
<%= f.text_area :message %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
And that´s it, you have your build in contact form.
This code is collected from one of my gems on github:
https://github.com/mattherick/contact_form
For testing you can add this gem to your gemfile and run the files generators, described in the github readme.

Related

How to add address to users with Google map and jt-rails-address?

I'm new on rails. I work on a project, and I try to add physical address to my users. I want that the address can be help-complete with Google map for later exploitation. I find the jt-rails-address which look like perfect for my project. But I can't implement it. I need complete address (street, zip code, city & country).
add_address_to_users.rb :
class AddAddressToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :address, :address
end
end
form edit.html.erb :
<div class="col-md-6 col-md-offset-3">
<%= form_for (#user), :html => { :multipart => true } do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :phone, "Téléphone :" %>
<%= f.phone_field :phone, class: 'form-control' %>
<%= f.label :address, "Addresse :" %>
<div class="jt-address-autocomplete">
<!-- This field is used to search the address on Google Maps -->
<%= f.text_field :address, class: 'jt-address-search' %>
<!-- All fields are hidden because the javascript will set their value automatically -->
<% for attr in JT::Rails::Address.fields %>
<%= f.hidden_field "address_#{street}", class: "jt-address-field-#{street}" %>
<% end %>
<% for attr in JT::Rails::Address.fields %>
<%= f.hidden_field "address_#{zip_code}", class: "jt-address-field-#{zip_code}" %>
<% end %>
<% for attr in JT::Rails::Address.fields %>
<%= f.hidden_field "address_#{city}", class: "jt-address-field-#{city}" %>
<% end %>
<% for attr in JT::Rails::Address.fields %>
<%= f.hidden_field "address_#{country}", class: "jt-address-field-#{country}" %>
<% end %>
</div>
<%= f.submit "Enregistrer les changements", class: "btn btn-primary" %>
<% end %>
</div>
application.js :
// This function is call when Google Maps is loaded
window.googleMapInitialize = function(){
// Simple usage
$('.jt-address-autocomplete').jt_address();
};
I have already put :address in my user_params in the users controller and has_address :address in the user model
I also have put my Google Api.
My actual error:
undefined local variable or method `street' for #<#Class:0x00007fe91ec7f768:0x00007fe91dfaefc0>
Thanks in advance for your help.
No more error but a bug, maybe because of Google Map, I don't know how
to resolve it, I can't write the address and there is an error message:
problem
Here the code of the inspector:
First, you should add fields like in documentation or scope them using select, now you have code that will create duplicated hidden fields.
You should check from rails console that method address is available on User instance of model.` Maybe you forgot to run migration or didn't restart server after installing this gem as this is js gem and will need restart.
Hope this answers your questions. Add comment to this answer if problem is still there.

Using a Method from Controller in Another Rails

I am using elasticsearch on my rails 4 app to search through my articles.
However, when an article is not found it redirects to a page where it alerts the user that no results are found, and allows to request a page. Instead of it saying "no results found" I want it to say "no results for ______ found" in which is takes the search bar query.
I have defined a method in the articles_controller in order to get the query but it won't show up on the page since the "no results page" uses a different controller.
What would be the best way to pull the method onto another controller or view in this case? Having trouble finding a straight forward answer for what I am trying to do. Thank you very much.
articles_controller:
def index
if params[:query].present?
#articles = Article.search(params[:query], misspellings: {edit_distance: 1})
else
#articles = Article.all
end
if #articles.blank?
return redirect_to request_path
end
get_query
end
private
def get_query
#userquery = params[:query]
end
new.html.erb (view for "no results found" page. Uses a different controller than articles page):
<body class="contactrequest">
<div class="authform" style="margin-top:15px">
<%= simple_form_for #request, :url => request_path do |f| %>
<h3 style = "text-align:center; color:red;">No results found. <%= #userquery %></h3>
<h1 style = "text-align:center; color:black;">Request a Page</h1>
<h5 style = "text-align:center; color:black; margin-bottom: 25px;">Our experts will gather the information,<br> and have your page us ASAP!</h5>
<%= f.error_notification %>
<div class="form-group">
<%= f.text_field :email, placeholder: 'Email', :autofocus => true, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.text_field :subject, placeholder: 'Item / Page Requested', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.text_area :content, placeholder: 'Any additional details...', class: 'form-control', :rows => '5' %>
</div>
<%= f.submit 'Request it', :class => 'btn btn-lg btn-danger btn-block' %>
<% end %>
As you can see I've tried calling that #userquery method to display on the view page, but it doesn't show up since it's defined on a different controller. Any recommendations would be awesome.
I would suggest you render results and no results from the same controller/view. A nice clean way to do this is with partials. Your view could look something like:
<% if #articles.blank? %>
<%= render 'no_results' %>
<% else %>
<%= render 'results' %>
<% end %>
Then, you would simply create _no_results.html.erb and populate it with your current new.html.erb contents and do the same for your nominal results page (with partial _results.html.erb).

In Rails with Globalize, update seems to ignore empty string fields

I am very new to Rails and I am facing a somehow weird problem, and my googling didn't helped me so far...
I have implemented a classical CRUD ressource following the Getting Started with Rails guide and I am blocking on the "update" part:
http://guides.rubyonrails.org/getting_started.html#updating-articles
This is part of my model "Devwork":
class Devwork < ActiveRecord::Base
validates :short_title, presence: true, uniqueness: true
validates :title_fr, presence: true, allow_blank: false
translates :title, :summary, :description
globalize_accessors
end
I am using the Globalize gem to persist localized data, and Globalize-accessor for the helpers.
Here is the controller's update action:
class DevworksController < ApplicationController
def update
#devwork = Devwork.find(params[:id])
if #devwork.update(devwork_params)
redirect_to #devwork
else
render :edit
end
end
private
def devwork_params
params.require(:devwork)
.permit!
end
end
And part of the form:
<%= form_for #devwork do |f| %>
<p>
<%= f.label :short_title %>
<%= f.text_field :short_title %>
</p>
<p>
<%= f.label :title_fr %>
<%= f.text_field :title_fr %>
<%= f.label :title_en %>
<%= f.text_field :title_en %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
short_title and title_fr are mandatory, while there exist another field title_en which is not. I want the update form to be shown again if the update fails (typically because of empty title_fr).
But it doesn't work. The update never fails (never entering render :edit) even if title_fr is empty. In fact, the update does nothing if one of the field is empty, it only updates non-empty fields.
I surely missed something somewhere, but I can't figure it out... perhaps a missuses of Globalize ?
Thanks for your help !

Problems using form helpers in ruby on rails

I have a class activity that has the follow atributes:
String type, Date date, String title
By including the associations it also has user_id and place_id.
class Activity < ActiveRecord::Base
belongs_to :user
belongs_to :place
In the other side User has many activities and place has many activities
So, the problem is when I want to create a new activity:
Scaffold creates the helper _form :
<%= form_for(#activity) do |f| %>
<% if #activity.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#activity.errors.count, "error") %> prohibited this activity from being saved:</h2>
<ul>
<% #activity.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :type %><br>
<%= f.text_field :type %>
</div>
<div class="field">
<%= f.label :date %><br>
<%= f.datetime_select :date %>
</div>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :user_id %><br>
<%= f.number_field :user_id %>
</div>
<div class="field">
<%= f.label :place_id %><br>
<%= f.number_field :place_id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I want to receive the first 3 fields from the form (type, date and title) but to associate a user and a place I have to do other way. I need the user that is actual logged in and the place is choosen by tiping the name.
My idea to do this is the following:
1) The user issue, I can make a query by using the current_logged_user that I have acess and get his ID.
2) The place issue, I can use the name that I receive from form and query my Places table for the place with the name X and get the ID after.
But, because I don't know too much about rails, how can I do this? How can I use f.text_field and then made the query or whatever and use after in the controller?
Controller has already this stuff :
def create
#activity = Activity.new(activity_params)
(...)
private
# Use callbacks to share common setup or constraints between actions.
def set_activity
#activity = Activity.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def activity_params
params.require(:activity).permit(:type, :date, :title, :user_id, :place_id)
end
You can structure your rails app to get neither the user_id nor the place_id directly from the form. Especially getting user_id from a submitted form is generally not a good idea. You usually do not want to whitelist user_id at all.
For user_id:
If you are using a gem like devise for user authentication, it gives you access to a method called current_user, which you can use to set the user_id from.
For place_id:
I suggest putting the activity as a sub route of place. e.g. instead of having the form under <host>/activities/new, put it under ``/places/:place_id/activities/new`. In your route file put the route as follows:
resources :places do
resources :activities
end
Now, in your controller action you can do the following:
def create
#activity = current_user.activities.new(activity_params)
#activity.place_id = params[:place_id] (or even safer will be #activity.place = Place.find(params[:place_id], but this will require one more sql query )
(...)
private
# Never trust parameters from the scary internet, only allow the white list through.
def activity_params
params.require(:activity).permit(:type, :date, :title)
end
UPDATE:
If you absolutely want to have the form under /activities/new route then you can have a select tag for place_id in your form:
select_tag 'activity[place_id]', options_from_collection_for_select(Place.all, 'id', 'name')
This will create a selection with name 'activity[place_id]' (named this way for params.require(:activity).permit(place_id) ) and options looking like
<option value="1">Barcelona</option>

How to convert a working rails contact form, into a bootstrap modal?

I currently have a working rails contact form (taken from another SO answer), available on /contact, that uses a controller, model and mailer (Mandrill). It responds to new and create routes in the controller, and still uses activemodel features. The form does not use ajax.
I now need to try to make my contact form work on the home page, as opposed to the /contact page via a modal pop-up.
I have read a number of SO queries, about modals, but all seem to be connected with getting a modal to do something specific - and not so much on creating a modal form to mimic a normal form.
To start I added a working modal, to the homepage.
When I then try to add the form into the homepage model, I run into method errors as the form is part of the home_controller. After copying my new and create controller actions into my home controller, I realized, that the form is just hidden, and is still being run when the page loads (by the index action).
Adding #message = Message.new into the index action does not seem to help - and wouldn't I want this on the modal load ?
Here are the main moving parts of my working form from the contact page, and the working modal box from the homepage - how can I merge the two and retain the functionality I have ?
here is the contact controller:
#/app/controllers/contact_controller.rb
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
the message model
#app/models/message.rb
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :subject, :body
validates :name, :email, :subject, :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
And the view:
<%= form_for #message, :url => contact_path do |form| %>
<fieldset class="fields">
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :email %>
<%= form.text_field :email %>
</div>
<div class="field">
<%= form.label :subject %>
<%= form.text_field :subject %>
</div>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
</fieldset>
<fieldset class="actions">
<%= form.submit "Send" %>
</fieldset>
<% end %>
Finally within my home page I have this for the modal (not containing the form)
<div class="modal fade" id="modal_contact_form">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Contact Form</h3>
</div>
<div class="modal-body">
<p>Test Content for Modal</p>
</div>
<div class="modal-footer">
</div>
</div>
Which is called by this <li>contact</li>
My attempts have been many and varied to get this working up until this point - the main issue I need to get my head around (I think) is that the form is loaded by the index action on the home_controller - Ideally I guess I still want to use the logic in my contact_controller ?
Any advice and suggestions appreciated - at this point I am wondering if there is an easy way just to move a form into a modal or not!
Cheers,
Mizpah
note: In response to queries I have about ajax, I have only avoided ajax due to perceived difficulty and lack of progress with trying it on rails 3.2 - I would be delighted to use it if it would actually be easier to turn this into an ajaxified form ?
It seems that I was not far away after all!
After a pointer from #rubyonrails channel, the answer was:
1) To copy the form as is, into the modal. (note that different styling is probably needed - but this answer gives the functionality needed).
2) To add #message = Message.new into the index action on my home_controller.rb
I had tried something very similar to this, but must of introduced another error, and thus bypassed the correct solution.

Resources