Routes in ruby with rails, html forms not working - ruby-on-rails

I am new to ruby with rails,I generated a new Controller named users by using command:
rails generate controller users register index login
After that I opened register.html.erb and wrote following code:
<h1>Register New User</h1>
<p>
<%= form_for :user do |f| %>
<%= f.label:USERID %><%= f.text_field:userid %><br />
<%= f.label:PASSWORD %><%= f.text_field:password %><br />
<%= f.label:EMAIL %><%= f.text_field:email %><br />
<br />
<%= f.submit %>
<% end %>
</p>
Then in users_controller.rb I wrote following code in register:
class UsersController < ApplicationController
def index
end
def show
end
def login
end
def register
print "test"
end
def user_params
params.require(:user).permit(:userid,:password,:email)
end
end
And test is not being printed and get and post methods of the form are not working at all.
And params.require(:user).permit(:userid,:password,:email) is not working as well. I get error that :user is empty.

I get error that :user is empty.
form_for(path/to/your/controller/action) is a helper method to create HTML form elements with the url path to the POST or GET request. The helper knows if it should be a new record or an update record based on what you are asking to do in your controller action. So, basically, it's looking for the #user in the corresponding controller action when you write form_for #user in your view. As you don't have it currently, hence you ar getting this error.
See this for more information.
To solve your current problem, you have to define the #user in the controller's register action:
def register
#user = User.new(user_params)
end
Then, in your register.html.erb file's form, you can use that #user:
<h1>Register New User</h1>
<p>
<%= form_for #user do |f| %>
<%= f.label :USERID %>
<%= f.text_field :userid %><br />
<%= f.label :PASSWORD %>
<%= f.text_field :password %><br />
<%= f.label :EMAIL %>
<%= f.text_field :email %><br />
<br />
<%= f.submit %>
<% end %>
</p>

Related

Get Request is passed instead of post request from new.html

I am trying out for basic login and registration in ruby on rails,
ISSUE: When I click register button from new.html I am getting GET request but I can see method="post" in page source of that html
I have posted my code below
new.html.erb
<form>
<%= form_for(#user) do |f| %>
<%= f.label :user_name %>
<%= f.text_field :user_name %></br>
<%= f.label :email_id %>
<%= f.text_field :email_id %></br>
<%= f.label :password %>
<%= f.password_field :password %></br>
<%= f.label :college %>
<%= f.text_field :college %></br>
<%= f.label :major %>
<%= f.text_field :major %></br>
<%= f.label :current_job %>
<%= f.text_field :current_job %></br>
<%= f.submit("Create Account",class: "btn btn-primary") %>
<% end %>
</form>
My index.html.erb code which is loaded while application starts
<div class="container">
<div class="row">
<div class="login">
<%= form_tag("/user/login",:method => :post) do %>
<%= label_tag(:EmailId) %>
<%= text_field_tag(:email, params[:email]) %></br>
<%= label_tag(:password) %>
<%= password_field_tag(:password, params[:password]) %></br>
<%= submit_tag("Log In",class: "btn btn-primary") %>
<%= submit_tag("Register",class: "btn btn-primary") %>
<% end %>
</div>
</div>
</div>
My controller code
class UsersController < ApplicationController
def index
#user = User.all
end
def login
print "In Sign in controller"
#user = User.new
if params[:commit] == 'Register'
print "inside Register class"
redirect_to '/users/new'
else
#user = User.find(params[:email_id])
if #user and user.authenticate(params[:password])
sessions[:userId] = #user.user_id
end
end
end
def new
puts "****Inside New Method******"
#user = User.new
end
def create
puts "****Inside create Method******"
end
private
def user_params
end
end
My Route code
Rails.application.routes.draw do
root 'users#index'
resources :users
post '/users/login' => 'users#login'
As per my understanding post request should hit create method, but get /users method is hitting. Please help me out regarding this
Why do you have nested forms in new.html.erb? Remove the first form tag
<form>
<%= form_for(#user) do |f| %>
You have a form tag inside another form tag. Remove the tag at the top of your form. <%= form_for(#user) %> takes care everything that's needed to build the correct form.

update record outside of namespaced admin [rails]

I have a named spaced admin in my app, where you can CRUD a client, this works great.
Outside of the admin within the app the #current_user has the opportunity to edit the client's address.
I am not sure how to access this and persist the new update to the database. this is what I have so far
products_controller.rb (where the partial is rendering from)
class ProductsController < ActionController::Base
layout "application"
def index
#products = Product.all
end
def show
#products = Product.all
#current_user = Client.find_by(id: session[:client])
end
end
_overlay_checkout.html.erb (this populates a form with the clients address from the db, and if its not updated they can change it.)
<%= simple_form_for([:admin, #current_user], :url => edit_admin_client_path) do |f| %>
<%= f.text_field :address %><br />
<%= f.text_field :address_line_2 %><br />
<%= f.select(:state, options_for_select(us_states, "CA")) %> <br />
<%= f.text_field :zipcode %><br />
<%= f.text_field :city %><br />
<%= f.submit %>
<% end %>
im unsure how I can update this record, ... without being in the admin section of the app, .. any help would be greatly appreciated.
One thing I've done in situations like this is to specify #submit_url as an instance variable in my controller action.
class ProductsController < ApplicationController
def show
#submit_url = client_path(#client)
end
end
You can can pass this variable to your form_for call like so:
<%= simple_form_for([:admin, #current_user], :url => #submit_path) do |f| %>
<%= f.text_field :address %><br />
<%= f.text_field :address_line_2 %><br />
<%= f.select(:state, options_for_select(us_states, "CA")) %> <br />
<%= f.text_field :zipcode %><br />
<%= f.text_field :city %><br />
<%= f.submit %>
<% end %>
If the #submit_url is not nil then the form action will be set to the value of the #submit_url otherwise it will get set to the resource based route that you specified. This means that in Admin Controller will not need to be changed at all. Just the alternate controller (in this case products_controller) where you want the submission of the form to go someplace other than the auto generated resourceful route.

Polymorphic user model when using devise

I am building a job board and therefore have two user models and employer and an applicant.
I am using devise and therefore my challenge now is to use this with the polymorphic relationship.
Through some rails console testing I know that (resource) in devise passes all the user information and it is passing the role_type which is either applicant or employer. However it is set to nil and therefore although my user is being saved it is not saving the role type of applicant or employer. Furthermore nothing is being saved in the applicant or employer tables just in the user table. My code is below but my question really is how do I pass the role_type to the devise resource hash? Or if this isnt possible the most elegant way of solving this problem.
Many Thanks!
Also the full project code is here if I have missed anything https://github.com/PatGW/jobs
Below is the views->devise->user->new.html.erb
<h1>Sign Up</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 :email %><br />
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</p>
<p>
<%= radio_button_tag :role_type, "employer", :checked => false %><br />
<%= label :role_type, 'Employer' %>
</p>
<p>
<%= radio_button_tag :role_type, "applicant", :checked => true %><br />
<%= label :role_type, 'Applicant' %>
</p>
<p class="button"><%= f.submit %></p>
<% end %>
UsersController which inherits from DeviseController
class UsersController < Devise::RegistrationsController
def new
super
end
def create
User.transaction do
super
after_sign_in_path(resource)
end
end
private
def after_sign_in_path(resource)
debugger
#user = User.new(params[:user])
if params[:role_type] == "coach"
role = Employer.create
else params[:role_type] == "player"
role = Applicant.create
end
end
end
The problem here is not Devise related, but association / OO related. I checked out your code: Your applicant and employer model seem to HAVE a user field, while those models should actually inherit from user, for they ARE a kind of user. So, try this:
class Employer < User
attr_accessible :location, :logo, :name
end
for starters, and see if it helps. (Btw: Obviously, you should also change the code for applicant)

Redirect to SHOW action in another controller

After creating a Person associated with a specific Account, how do I redirect back to the Account page?
The account_id is passed to the CREATE Person action via a URL parameter as follows:
http://localhost:3000/people/new?account_id=1
Here is the code:
<h2>Account:
<%= Account.find_by_id(params[:account_id]).organizations.
primary.first.name %>
</h2>
<%= form_for #person do |f| %>
<%= f.hidden_field :account_id, :value => params[:account_id] %><br />
<%= f.label :first_name %><br />
<%= f.text_field :first_name %><br />
<%= f.label :last_name %><br />
<%= f.text_field :last_name %><br />
<%= f.label :email1 %><br />
<%= f.text_field :email1 %><br />
<%= f.label :home_phone %><br />
<%= f.text_field :home_phone %><br />
<%= f.submit "Add person" %>
<% end %>
class PeopleController < ApplicationController
def new
#person = Person.new
end
def create
#person = Person.new(params[:person])
if #person.save
flash[:success] = "Person added successfully"
redirect_to account_path(params[:account_id])
else
render 'new'
end
end
end
When I submit the above form I get the following error message:
Routing Error
No route matches {:action=>"destroy", :controller=>"accounts"}
Why is the redirect_to routing to the DESTROY action? I want to redirect via the SHOW action. Any help will be greatly appreciated.
params[:account_id] exists in the form, but when you pass it to create you're sending it along in the person hash, so you'd access it via params[:person][:account_id]
params[:account_id] is nil, hence the bad route. To be honest, I'm not sure why, but resource_path(nil) ends up routing to destroy instead of show. In either case, it's a broken route without an id parameter.
# so you *could* change it to:
redirect_to account_path(params[:person][:account_id])
# or simpler:
redirect_to account_path(#person.account_id)
# but what you probably *should* change it to is:
redirect_to #person.account
Rails will inherently understand this last option, ascertaining the path from the class of the record, and getting the id from #to_param
I would not be pass this through using a hidden_field. Instead, use nested resources:
resources :account do
resources :people
end
Then have an account object for the form:
<%= form_for [#account, #person] do |f| %>
...
<% end %>
This #account object should be set up in the action that renders the form with a line like this:
#acccount = Account.find(params[:account_id])
Then when the form is submitted you'll have params[:account_id] in that action without the ugly hidden_field hack to get it there.
Yippee!

Rails populate edit form for non-column attributes

I have the following form:
<% form_for(#account, :url => admin_accounts_path) do |f| %>
<%= f.error_messages %>
<%= render :partial => 'form', :locals => {:f => f} %>
<h2>Account Details</h2>
<% f.fields_for :customer do |customer_fields| %>
<p>
<%= customer_fields.label :company %><br />
<%= customer_fields.text_field :company %>
</p>
<p>
<%= customer_fields.label :first_name %><br />
<%= customer_fields.text_field :first_name %>
</p>
<p>
<%= customer_fields.label :last_name %><br />
<%= customer_fields.text_field :last_name %>
</p>
<p>
<%= customer_fields.label :phone %><br />
<%= customer_fields.text_field :phone %>
</p>
<% end %>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
As well as
attr_accessor :customer
And I have a before_create method for the account model which does not store the customer_fields, but instead uses them to submit data to an API.. The only thing I store are in the form partial..
The problem I'm running into is that when a validation error gets thrown, the page renders the new action (expected) but none of the non-column attributes within the Account Detail form will show?
Any ideas as to how I can change this code around a bit to make this work me??
This same solution may be the help I need for the edit form, I have a getter for the data which it asks the API for, but without place a :value => "asdf" within each text box, it doesn't populate the fields either..
Okay, what you need to do is create a class to handle your customer with and without a Braintree gateway connection. First, create the class:
class Customer
attr_accessor :company, :first_name, :last_name, :phone, :gateway
def initialize gateway_id=nil
begin
#gateway = Braintree::Customer.find(gateway_id) unless gateway_id.nil?
rescue Braintree::NotFoundError
end
end
def company
#gateway.nil? ? #company : #gateway.company
end
# Implement the rest of the methods this way as well. You can even use
# meta-programming so that you don't repeat yourself.
end
You'll notice that calling Customer.new(id).company will work with and without an id or gateway, because if a gateway non-existent #company will be returned, and if a gateway is present the gateway's company will be returned.
Finally, hook this into your model:
class Account
def customer
#customer ||= Customer.new(self.gateway_customer_id)
end
def customer= h
#customer = Customer.new
#customer.company = h[:company]
...
#customer
end
end
You'll have to modify how you write code to the API so that you use customer.company instead of customer[:company] for example, but you can probably write a function within the Customer class to do this easily.
You'll have to modify your form to:
<% f.fields_for :customer, #account.customer do |customer_fields| %>

Resources