Instance Variables in a Partial for Sign-Ups - ruby-on-rails

I am currently working on a website that will require users to sign-up, in order to perform various tasks. However, I am having some trouble with sign-ups.
I have a partial named _form.html.erb, which is rendered in application.html.erb (so that it appears on every page users navigate to) as a fade-in, fade-out modal form (I am using Twitter Bootstrap). What do I need to do, in order to pass an instance variable to this partial and have a user created in the database, once the user presses the submit button? Do I need to create a new method in application_controller.rb and a new user model?
Thank you for the help!
Note: I've read this link (http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials), but did not get much out of it.

I would assign a local variable when rendering the partial that stores the user object.
layouts/application.html.erb
<%= render "users/form", :user => User.new %>
users/new.html.erb
<%= render "form", :user => #user %>
Using this technique your form would reference the local variable.
<%= form_for user do |f| %>
<!-- form fields here -->
<% end %>

Related

would it be ok to create an instantiate an object in another controller?

I have a controller for customer. In the new action, I redirect to another page, which belong to the pages controller
class CustomersController < ApplicationController
def new
redirect_to register_path
end
Would it be possible to create the object in the registration action like this?
class PagesController < ApplicationController
def registration
#customer = Customer.new
end
end
I believe the setup is something like this: you have models in your application for a Customer and, say, an Agent. Your website users register as either and the desire is to have a single HTML page (URL) with both options available. They choose which one they are and submit some fields, say name/email/password. To keep it simple, without bothering with JavaScript to hide things behind tabs, you have something like:
**Customer**
Name: ___________
Email: __________
Password: _______
[Submit]
**Agent**
Name: ___________
Email: __________
Password: _______
[Submit]
You have a few options here to avoid your guilty feeling in the Rails controllers:
Go heavy client-side JavaScript. Don't have the new actions on the controllers. The JavaScript creates the page elements. The create action becomes a JSON API endpoint, thereby avoiding the problem in the Ruby application. This is obviously a significant architectural deviation from where I think you are today.
Use a little bit of JavaScript to dynamically load the correct 'partial' into the DOM when the user switches between the options. Avoids the underlying problem in the question by effectively separating the 'pages' out to the two controllers. The Pages→registration action does not need to set any instance variables for the view. The JavaScript deals with the partial loading. (see 'link_to' and the 'remote' option)
Don't include both forms in the same HTML page, just default to one, say the Customer one, and provide a link to navigate to the Agent one, e.g. a link in a tab, or a plain link like "Not a Customer? Register as an Agent." In this scenario, you have a neat mapping to the Ruby MVC design, each of the pages are just the new action of its relevant controller. The downside is a page load to change between the two options. This is the simplest, plainest choice … if you can get the boss to agree to the UX. PS: if you are using turbolinks, then the 'feel' of this option in the browser will be not far from option (2).
Stick to your design
Keep in mind that you will have difficultly dealing with error conditions and messages with option (4). You can do it, but the code won't be simple or easy to maintain.
If option (4) is a must, one simplification can be the create actions on each of the controllers rendering their own new in case of an error. If you submit the 'Agent' form from your starting page, with errors, to the Agents→create action, that action finishes with a render 'new' to show the user the Agents→new page. No 'customer' form is visible. You could then add a sprinkle of option (3) in there with a "Not an Agent? Register as a Customer." link under the form. Doing this greatly simplifies your error handling.
Which then leads to a suggestion for your original problem. Cheat. Don't have an #customer instance variable for the new actions (or the registration action). Use partials for the customer and agent forms, and pass in a new object to form_for, e.g.
pages/registration.html.erb
<%= render 'customers/new_form' %>
<%= render 'agents/new_form' %>
customers/new.html.erb
<%= render 'customers/new_form' %>
customers/_new_form.html.erb
<% form_for Customer.new do |f| %>
<%# include the inputs shared with the edit action %>
<%= render 'fields', f %>
<%= f.submit %>
<% end %>
customers/_fields.html.erb
<%# 'f' is one of the locals passed to the partial %>
<% f.input_field :name %>
<% f.email_field :email %>
<% f.password_field :password %>
customers/edit.html.erb
<% form_form #customer do |f| %>
<%= render 'fields', f %>
<%= f.submit %>
<% end %>
… then you would follow the same pattern for:
agents/new.html.erb
agents/_new_form.html.erb
agents/_fields.html.erb
agents/edit.html.erb

Ruby on Rails - Session variable on form submit

I have an application which requires visitors to fill out a form and then it redirects to a second page. The client does not want to require visitors sign up to view this page, only to fill out the form.
The way I am attempting to do this is by creating a session variable when the page is visited and then checking to see if the variable exists before the next page is accessible. Is it possible to delay the creation of the session variable until the submit action is processed? If so what would that look like?
Also, can anyone think of a better way to do this? Sorry, this is probably a dumb question.
The session cookie would be declared after the first submit.
I presume the first submit will load up a controller#action in which you'll then redirect to the next page. Just set the session in there:
#app/views/forms/1.html.erb
<%= form_tag form_1_submit_path do %>
...
<% end %>
This will allow you to do the following:
#app/controllers/forms_controller.rb
class FormsController < ApplicationController
def form_1_submit
session[:value] = params[:value]
redirect_to form_2
end
end
Thus you'll have session[:value] all set and ready to use on the next form:
#app/views/forms/2.html.erb
<%= form_tag .... do %>
<%= text_field_tag :test, value: session[:value] %>
<% end %>

Rails "form_for" action, how redirect to a different path depending of kind of user

I am using Devise as my authentication on a Rails app.
The User form works fine, but I want it to redirect to a different path depending on where the person starts on the site.
So all people (customers, contractors) are Users. But if you sign up to apply to be a new Contractor I want to send you to the new application form. If you are a customer you need to go to a different page with a different form.
I am new(again) to Rails and can not figure out how to do this. Is it something I can change in "form_for" directly in the view or something that needs to be done in the controller.
UPDATE:
<%= form_for(resource, as: resource_name, url: new_contrator_path(resource_name)) do |f| %>
ERROR:
undefined method `new_contrator_path' for #<#:0x007f88834bec28>
I am sure I am screwing up something in a controller...
2nd UPDATE
I am using this with 'scout_app' as the hidden field
<%= f.hidden_field :type, value: "scout_app" %>
This is what I have in the new user form but I can't get it to pass the attribute to the User. It always has NIL
You can use the url parameter in form_for.
For example:
<%= form_for(#post, url: custom_path) do |f| %>
...
<% end %>
You can override default sign_in method of devise and redirect as per your requirement in your application_controller.rb file
def after_sign_in_path_for(resource)
# your code
end

Fire up custom action when user clicks 'Search" on RAILS 3.2 form?

Is it possible to fire up an custom action when user clicks 'Search' button on search form?
There is an mechanism in our app to save every URL the app has hit. In our search form, when clicking 'Search' button, there will bring up the search result page. The problem is that the URL for the search result form was not saved. The Back button brings back the search page (for setup search params) instead of the search result page (because its URL was not saved).
Here is the search form for model configs:
<h4>Search Form></h4>
<%= simple_form_for #config, :method => :get, :url => search_result_configs_path do |f| %>
<%=render :partial => 'search_params', :locals => {f: f} %>
<%= f.button :submit, t('Search') %>
<% end %>
The URL for the search result looks like this (with the search params set by user) after user clicks Search button:
http://localhost:3000/configs/search_results?utf8=%E2%9C%93&engine_config[start_date_s]=&engine_config[end_date_s]=&engine_config[engine_id_s]=1&engine_config[argument_name_s]=&engine_config[commissioned_s]=&commit=%E6%90%9C%E7%B4%A2
This is the URL we would like the app to remember. We figure we need custom action triggered when a user clicks 'Search' button. Is it possible?
Route
Firstly, calling a custom application is actually quite a simple process - you just need to call its route:
#config/routes.rb
resources :search do
collection do
get :custom_action
end
end
This will allow you to use the likes of form_tag to call the custom route:
#app/views/your_controller/view.html.erb
<%= form_tag search_custom_action_path, method: :get do %>
...
<% end %>
--
Form
Secondly, you're using simple_form for your search form.
This is completely fine, but the problem you have here is that when you use this, it has to have a ActiveRecord object to populate the form with. This is probably where you're getting confused, as to do this, you need ot make sure #config is available every time you load that form, which I imagine can be a lot.
We've created a search form here:
Although in Rails 4, we used a form_tag for this form, as it allowed us to create & display the form where-ever we need in the app. This allows us to pass the required params through the form & access them on the other side
--
Params
You mention you want to "save the URL" - what do you mean by this?
Surely you'd prefer to save the params?
If this is true, the way to do this is actually relatively simple - you'll get access to the params hash in your controller when you send the request through:
#app/controllers/your_controller.rb
Class YourController < ApplicationController
def custom_action
params[:your_param] #-> this is accessible here
end
end
The bottom line is if you wanted to save the query strings, you'll have to create a model called Search or similar, allowing you to pass the params through when you process the custom action in your controller, just like you would any other ActiveRecord object

rails form_for creates a new database entry on refresh, without form submit

I'm new to rails and mongodb, and have a simple form attempting to create a category tree.
Whenever I refresh the page, a new entry is put into the database.
I'm not clicking the 'submit' button, just page refresh.
The form looks like this
<%= form_for Activity.create do |f| -%>
<%= f.text_field :activity_name % >
<%= f.submt "add action" %<
<% end %>
my model is
class Activity
include MongoMapper::Document
key :activity_name, :type => String
key :parent, :type => ObjectId
key :acnestors, Array
timestamps!
end
my routes has a single entry for activity
map.activity '/activity/:activity_id', :controller => 'activities', :action => 'show'
though I call create from the form, my create function in my controller is empty.
The form is included in the show page via render, but that shouldn't matter.
Any idea why a page refresh would act as a form submit?
You are calling Activity.create in your form helper. This is going to create (in the Rails sense, which will also save it to the db) a new object every time you load the page.

Resources