new find view is being processed as new create request - ruby-on-rails

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 >

Related

How do add the message option to validates_uniqueness_of :user_id, :scope => :task_id in Rails model?

I have a Rails model DoRequest.
class DoRequest < ActiveRecord::Base
include AASM
default_scope -> { order('created_at DESC') }
belongs_to :task
belongs_to :user
validates_uniqueness_of :user_id, :scope => :task_id, :message =>"Your application cannot be processed"
aasm :column => 'state', :whiny_transitions => false do
state :pending
state :accepted
state :rejected
event :accept do
transitions :from => :pending, :to => :accepted
end
event :reject do
transitions :from => :pending, :to => :rejected
end
end
end
I added the uniqueness validation with the scope as I intended for each instance of the model to have a unique user_id and task_id combination.
Now that the validation is added I get an error every time I am trying to create a new DoRequest instance with the same value [:user_id, task_id].
The error says undefined method `id' for nil:NilClass in the line :
undefined method `id' for nil:NilClass in the line:
<%= form.hidden_field :task_id, value: #task.id %>
in the app/views/do_requests/new.html.erb:
<%= form_for #do_request, method: :post do |form| %>
<div class= "form form-actions" >
<%= form.hidden_field :task_id, value: #task.id %>
<%= form.label :application, "Please write your application here and the project administrator will get back to you" %><br>
<%= form.text_area :application, :rows => 20, :cols => 60 %>
<% if params[:free] == 'true' %>
<%= form.hidden_field :free, value: true %>
<%elsif params[:free] == 'false' %>
<div class="checkbox" style="width:150px">
<label>
<%= form.check_box :free %> Do for free
</label>
</div>
<%end%>
<%= submit_tag "Send Application", class: 'btn btn_primary' %>
<%= link_to "Cancel", task_path(#task), class: 'btn' %>
</div>
<%end%>
I would like instead the error to redirect the user back and display the message: "You cannot apply twice for the same task".
How do I do this.
Here is my controller:
class DoRequestsController < ApplicationController
before_filter :authenticate_user!
def index
end
def new
#task = Task.find(params[:task_id])
#free = params[:free]
end
def create
#do_request = current_user.do_requests.build(request_params)
if #do_request.save
flash[:success] = "Request sent to Project Admin"
redirect_to #do_request.task
else
render 'new'
end
end
def update
end
def destroy
#do_request = DoRequest.find(params[:id])
#do_request.destroy
respond_to do |format|
format.html { redirect_to current_user, notice: 'Task assignment request was successfully destroyed.' }
format.json { head :no_content }
end
end
def accept
#do_request = DoRequest.find(params[:id])
if #do_request.accept!
#do_request.user.assign(#do_request.task, #do_request.free)
flash[:success] = "Task has been assigned"
else
flash[:error] = "Task was not assigned to user"
#assign(#do_request.user, #do_request.task, #do_request.free)
end
end
def reject
#do_request = DoRequest.find(params[:id])
if #do_request.reject!
flash[:succes] = "Request rejected"
else
flash[:error] = "Was not able to reject request"
end
end
private
def request_params
params.require(:do_request).permit(:application, :task_id, :user_id, :free)
end
end
Use this on your def create
def create
#do_request = current_user.do_requests.build(request_params)
if #do_request.save
flash[:success] = "Request sent to Project Admin"
redirect_to #do_request.task
else
#task = Task.find(params[:do_request][:task_id])
#free = params[:free]
render 'new'
end
end
or just use
<%= form.hidden_field :task_id %>
on your form

I don't get why this platformatic mail form contact form isn't working

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.

How save input from static page to database in rails

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.

Nil object when you didn't expect it for contact form_for

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|

How can I test the file upload and controller?

My view
<%= form_tag({:action => 'upload_image', :car_id => #car.id}, :multipart => true) do %>
<label for="upload_file"><%= t('field.select_image') %></label>
<%= file_field 'upload', 'datafile' %> <%= submit_tag t('field.upload_file') %>
<% end %>
My controller
def upload_image
if params[:upload].present? && params[:car_id].present?
DataFile.save_image_file(params[:upload][:datafile], params[:car_id]) # My methods to save image and other operations with file
end
redirect_to images_path(:car_id => params[:car_id])
end
My Rspec Test (doesn't work)
before :each do
#car = FactoryGirl.create(:car)
#file = fixture_file_upload('/files/test-bus-1.jpg', 'image/jpg')
end
it "can upload a car" do
post :upload_image, :upload => #file, :car_id => #car.id
response.should redirect_to images_path(:car_id => #car.id)
end
Error: Failure/Error: post :upload_image, :upload => #file, :car_id => #car.id
NoMethodError:
undefined method `[]' for # File:/tmp/test-bus-1.jpg20120826-29027-plg28d
What's wrong?
It looks to me, based on how you've set up your form (since you are calling params[:upload][:datafile]), that you need to change your rspec test to:
post :upload_image, :upload => { :datafile => #file }, :car_id => #car.id

Resources