i want to save a input "email" from static pages to the database. Right now, i have a emails model with a :address field, but i can't save the value when click the submit input.
Layout with form
# layout/website.html.erb
<div>
<%= form_for #email, :url => newsletter_path, :method => :post do |email| %>
<%= email.text_field :address %>
<%= email.submit "Go" %>
<% end %>
</div>
Pages Controller
# controllers/pages_controller.rb
def home
newsletter
end
def newsletter
#email = Email.new(params[:address])
if #email.valid?
redirect_to(request.referer, :notice => "The suscription has been sent successfully.")
else
redirect_to(request.referer, :alert => "Please add an valid email address.")
end
end
Routes
# routes.rb from static pages
get "/home" => 'pages#home', :as => :home
get "/pricing" => 'pages#pricing', :as => :pricing
get "/logo-gallery" => 'pages#logo_gallery', :as => :logo_gallery
get "/blog" => 'pages#blog', :as => :blog
get "/blog/:id" => 'pages#post', :as => :post
get "/contact" => 'pages#contact', :as => :contact
match '/contact' => 'pages#create', :as => :contact, :via => :post
get "/faqs-and-terms" => 'pages#faqs_and_terms', :as => :faqs_and_terms
match "/newsletter" => 'pages#newsletter', :as => :newsletter, :via => :post
Model
# models/email.rb
class Email < ActiveRecord::Base
attr_accessible :address
validates :address, :format => { :with => %r{.+#.+\..+} }, :allow_blank => true
end
With this code, when visit /home right now i'm received:
ActionController::ActionControllerError in PagesController#home
Cannot redirect to nil!
I hope you can help me, what can i do to fix this and get a better code. Thank you.
You should use Email.create(params[:email]) instead of Email.new(params[:address]) to persist records in DB. Also, in your view you code add hidden_field
<%= email.text_field :address %>
<%= hidden_field_tag :referer, :value => request.path %>
<%= email.submit "Go" %>
And then in controller:
redirect_to params[:referer]
UPD
Also, please notice that you should use params[:email] in your controller, not params[:address]. You can invoke raise params.inspect in your controller to inspect params sent by form.
In newsletter action email record is only initialized but not saved. And you have no need to call newsletter method inside home action every time. Just update your code like this.
Pages Controller
# controllers/pages_controller.rb
.....
# no need to call newsletter action here
def home
end
def newsletter
#email = Email.new(params[:email])
if #email.save
redirect_to((request.referer || '/'), :notice => "The suscription has been sent successfully.")
else
redirect_to((request.referer || '/'), :alert => "Please add an valid email address.")
end
end
Layout with form
As #email is not defined in controller, so you should initialize an Email object in form.
# layout/website.html.erb
<div>
<%= form_for Email.new, :url => newsletter_path, :method => :post do |email| %>
<%= email.text_field :address %>
<%= email.submit "Go" %>
<% end %>
</div>
I hope that it should work.
Related
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 following this Ruby Railcasts episode to get some simple auth going, and I'm getting the error uninitialized constant Sessions when I navigate to the login page. I've checked my classes and the names are proper, which seems to be the problem most people report. Any idea what might be happening here?
The name of my controller file is sessions_controller.rb and the code is as follows:
class SessionsController < ApplicationController
def new
end
def create
user = User.authenticate(params[:email], params[:password])
if user
session[:user_id] = user.id
redirect_to root_url, :notice => 'Logged In!'
else
flash.now.alert = 'Invalid email or password'
render 'new'
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => 'Logged Out!'
end
end
routes.rb file:
Albumtracker::Application.routes.draw do
get "login" => "sessions/new", :as => "login"
get "logout" => "sessions/destroy", :as => "logout"
get "signup" => "users/new", :as => "sign_up"
root :to => 'users#new'
resources :users
resources :sessions
get "pages/index"
end
sessions/new view file:
<h1>Log in</h1>
<%= form_tag sessions_path do %>
<p>
<%= label_tag :email %><br />
<%= text_field_tag :email, params[:email] %>
</p>
<p>
<%= label_tag :password %><br />
<%= password_field_tag :password %>
</p>
<p class="button"><%= submit_tag "Log in" %></p>
<% end %>
You have typos in your routes. / should be # when specifying a controller and action. Your routes should look like this:
get "login" => "sessions#new", :as => "login"
get "logout" => "sessions#destroy", :as => "logout"
get "signup" => "users#new", :as => "sign_up"
When you use / in your route the preceding portion is matched to a namespace. So from "sessions/new" the router was trying to locate a controller named Sessions::NewController. Since the namespace Sessions doesn't exist in your app, you got the uninitialized constant error.
I had a question earlier on this, I am trying to make a ldap search form.
So far I did rails generate for users/find. In the model I have a function to search a user in ldap, which works fine independently outside of rails.
but the request through this view is actually getting treated as a request to create a new user, instead to just search the user in ldap.
I am new to rails, dont what the missing link is. Need some help here understanding this, in future there will be a lot of functions/features like this I have to add in this test app. Which I think will probably lead to the same issue.
# rails generate controller users find
error -
undefined method `gsub' for nil:NilClass
Started GET "/users/find" for 10.85.41.23 at 2012-04-05 19:56:27 -0400
Processing by UsersController#find as HTML
Completed 500 Internal Server Error in 15ms
NoMethodError (undefined method `gsub' for nil:NilClass):
app/models/user.rb:54:in `FindActiveDirectory'
app/controllers/users_controller.rb:10:in `find'
Model -
class User < ActiveRecord::Base
attr_accessible :user_id, :firstname, :lastname, :email, :role, :misc, :password
validates_presence_of :user_id, :firstname, :lastname, :email, :role, :on => :create
validates_uniqueness_of :user_id, :email
ROLES = ['Admin','User']
####################
SERVER = '10.10.10.1'
PORT = 389
BASE = 'DC=User,DC=mysite,DC=com'
DOMAIN = 'ldap.mysite.com'
####################
def self.ActiveDirectoryAuthenticate(login, pass)
user = find_by_user_id(login)
if user
nil
else
return false
end
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => { :username => "#{login}##{DOMAIN}",
:password => pass,
:method => :simple }
if conn.bind
return user
else
return false
end
rescue Net::LDAP::LdapError => e
return false
end
def self.FindActiveDirectory(login)
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => { :username => 'admin',
:password => 'adminpass',
:method => :simple }
if conn.bind
conn.search(:base => BASE, :filter => Net::LDAP::Filter.eq( "sAMAccountName", login ),
:attributes => ['givenName','SN','mail'], :return_result => true) do |entry|
entry.each do |attributes, values|
if "#{attributes}" == "sn"
values.each do |value|
puts "Lastname: "+"#{value}"
$lastname = "#{value}"
end
end
if "#{attributes}" == "givenname"
values.each do |value|
puts "Firstname: "+"#{value}"
$firstname = "#{value}"
end
end
if "#{attributes}" == "mail"
values.each do |value|
puts "Email: "+"#{value}"
$email = "#{value}"
end
end
end
end
return true
else
return false
end
rescue Net::LDAP::LdapError => e
return false
end
end
controller -
class UsersController < ApplicationController
def new
#user = User.new
end
def find
#user = User.FindActiveDirectory(params[:user_id])
end
def create
#user = User.new(params[:user_id])
if #user.save
redirect_to users_added_url, :notice => "Signed up!"
else
render "new"
end
end
end
View -
<h1>Users#find</h1>
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :Username %><br />
<%= f.text_field :user_id %>
</p>
<p class="button"><%= f.submit %></p>
<% end %>
routes -
rubyapp::Application.routes.draw do
get "users/find"
get "myapp/new"
root :to => "sessions#new"
#root :to => "home#index"
get "sessions/new"
get "users/new"
get "users/added" => "users#added"
get "myapp" => "myapp#new"
get "log_out" => "sessions#destroy", :as => "log_out"
get "log_in" => "sessions#new", :as => "log_in"
get "sign_up" => "users#new", :as => "sign_up"
resources :users
resources :sessions
end
You need another method to handle the data you returned:
the controller:
def find
end
def display_result
#result = User.findActiveDirectory( params[:user_id] )
if #result.empty?
render action: "find", notice: "Could not find a user with id #{params[:user_id]}"
end
end
next step is to add a route to the routes.rb:
get 'users/find'
post 'users/display_result'
now we have to update the view for find:
<h1>Users#find</h1>
<p><%= notice %></p>
<%= form_tag users_display_result_path do %>
<p>
<%= label_tag :Username %><br />
<%= text_field_tag :user_id %>
</p>
<p class="button"><%= submit_tag %></p>
<% end %>
and create the new view for displaying the result (this one is very basic, i guess you need to improve this a lot, but this should give you an idea):
<h1>Users#display_result</h1>
<%= debug #result %>
and last but not least change some stuff in the model:
def self.FindActiveDirectory(login)
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => { :username => 'admin',
:password => 'adminpass',
:method => :simple }
if conn.bind
result = HashWithIndifferentAccess.new
conn.search( :base => BASE,
:filter => Net::LDAP::Filter.eq( "sAMAccountName", login ),
:attributes => ['givenName','SN','mail'],
:return_result => true
) do |entries|
entries.each do |attribute, value|
result[attribute] = value
end
end
return result
rescue Net::LDAP::LdapError => e
return false
end
You will end up in the controller/ view with a variable called #result. This variable is a hash with the attributes as key. So you could do something like this in the view:
<% #result.each do |key,value| %>
<%= key.to_s.normalize + ": " + value.to_s %>
<% end >
I'm super new to Ruby on Rails. I'm trying to make an authentication system using Authlogic (following this tutorial). The error that I'm getting is right after I submit the login form:
No route matches "/user_sessions/%23%3CUserSession:0x103486aa8%3E"
Surprisingly the URL of the page right after the form is submitted which also brings up the error is:
http://localhost:3000/user_sessions/%23%3CUserSession:0x103486aa8%3E
I have no idea what I have done wrong and where that weird UserSession code thing is coming from!!!
This is how my login form looks like:
<% form_for #user_session do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :username %><br />
<%= f.text_field :username%>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
Here is my UserSession class:
class UserSession < Authlogic::Session::Base
def to_key
new_record? ? nil : [ self.send(self.class.primary_key) ]
end
end
and the create action of my UserSessionController:
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default root_path
else
render :action => :new
end
end
"redirect_back_or_default" method in ApplicationController:
def redirect_back_or_default(default)
redirect_to(session[:return_to] || default)
session[:return_to] = nil
end
And lastly everything related to user_sessions in routes.rb:
resources :user_sessions
match 'login' => "user_sessions#destroy", :as => :login
match 'logout' => "user_sessions#destroy", :as => :logout
These are the codes that I thought could be involved in getting that error. If I should add some more code to make it more clear please let me know.
Ok, first, you have a bad route:
match '/login', :to => 'user_sessions#new', :as => 'login'
note the new instead of destroy
also, the to_key is not needed in later versions - I'm using rails 3 and don't have it in my UserSession Model.
Definitely need to change your route to not match login to destroy.
Here's the route setting I have... (from "Agile Web Development with Rails" example).
controller :user_sessions do
get 'login' => :new
post 'login' => :create
delete 'logout' => :destroy
end
I'm making a website with a page where users can sign up to win an iPad. I created a model ipad.rb and an ipads_controller.rb and there were three columns in the migration for name, email and twitter handle. I was surprised when Rails didn't create routes automatically (I thought it was supposed to do that always).
I added this in the routes file
resource :ipad
match '/signup', :to => 'ipads#new'
When I tried to create the sign up form, I got this error message before fully completing it
undefined method `ipads_path' for #<#<Class:0x00000103a64ec0>:0x00000103a49aa8>
This surprised me because why was it plural?
So far I've only created a form in new.html.erb and the model ipad.rb and two actions in the ipads_controller.rb new and create.
Can anyone see what i'm doing wrong? i.e. why does Rails think I need a method ipads_path. Also note that I had created a model IPad.rb but deleted it and the migrations.
new.html.erb
<h1>Win an iPad</h1>
<h1>Sign up for iPad</h1>
<%= form_for(#ipad) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
ipad.rb
class Ipad < ActiveRecord::Base
attr_accessible :name, :email, :twitter
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :email, :presence => true,
:format => { :with => email_regex },
:uniqueness => true
end
ipads_controller.rb
class IpadsController < ApplicationController
def new
#ipad = Ipad.new
#title = "iPad Contest"
end
def create
#ipad = Ipad.new(params[:ipad])
if #ipad.save
# Handle a successful save.
else
#title = "iPad Contest"
render 'new'
end
end
end
routes.rb
Enki::Application.routes.draw do
namespace 'admin' do
resource :session
resources :posts, :pages do
post 'preview', :on => :collection
end
resources :comments
resources :undo_items do
post 'undo', :on => :member
end
match 'health(/:action)' => 'health', :action => 'index', :as => :health
root :to => 'dashboard#show'
end
resources :archives, :only => [:index]
resources :pages, :only => [:show]
resource :ipad
match '/signup', :to => 'ipads#new'
constraints :year => /\d{4}/, :month => /\d{2}/, :day => /\d{2}/ do
get ':year/:month/:day/:slug/comments' => 'comments#index'
post ':year/:month/:day/:slug/comments' => 'comments#create'
get ':year/:month/:day/:slug/comments/new' => 'comments#new'
get ':year/:month/:day/:slug' => 'posts#show'
end
scope :to => 'posts#index' do
get 'posts.:format', :as => :formatted_posts
get '(:tag)', :as => :posts
end
root :to => 'posts#index'
end
Your resource 'ipad' should be plural in the routes, i.e.
resources :ipads