I can't find a way to use views from other views.
I think I can explain it better with this example: I have two controllers, IndexController and UserController. The user controller has an action called login with its view which renders the login form and validates the user when a post from its form happens.
In IndexController, there is an action called home which renders the home page view. In this view I want to render the loginform, but I want to re-use the user/login view.
In almost all the frameworks I worked with there is a way to call another controller action in order to re-use and isolate the logic.
I find that, in Rails, there is a helper render that I can call in the following way:
render 'user/login'
or
render :template => 'user/login'
In both cases I only get errors like "the route index/login does not exist" or "the controller index has to login action". Besides, I set the login view file name as login or _login. (I read that is used for partial views.)
You can do this by creating a shared folder within your views folder and create the login form as a partial.
So your login partial might be something like this.
/app/views/shared/_loginform.html.erb:
<div id="loginform">
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
<%= f.text_field :email %>
<%= f.password_field :password %>
<%= f.submit "Login" %>
<% end %>
<div id="loginlinks">
<%= link_to "Become a member", new_member_registration_path %> <br />
<%= link_to "Forgot Password?", new_member_password_path %>
</div>
</div>
Then in your views just call:
<%= render "shared/loginform" %>
You should take a look at Railscast: "#269 Template Inheritance".
Since Rails 3.1, controller inheritance now applies to views as well. This is preferred over the older "shared folder" strategy.
In short, you put your shared partials in app/views/application then you can override them in your resource specific view directories (e.g app/views/users).
Related
I want to make erb template of searchbar that will call search method of its controller. Different controllers got same method, but will have different logic. Is it possible to make form that will work with every controller just by rendering it on their views?
--- UPDATE ---
I have found that kind of solution:
<%= form_tag "#{controller_name}/search", method: 'get' do %>
<div class="input-group">
<%= text_field_tag :sub_string, '', class: 'form-control', placeholder: "Search..." %>
<span class="input-group-btn">
<%= submit_tag 'Search', class: %w(btn btn-primary) %>
</span>
</div>
<% end %>
However when I hit the submit button, it goes to search action of my current controller and it thows an error:
Couldn't find Basis with 'id'=search
it tries to call set_basis private method, even if it is not called by before_action?
Set search form's controllers name with params[:controller].
Use Rails Guide to see how to pass controller and action for a form_tag or form_for.
I think you can
create the template/partial under views/shared folder
then in controller do something like
def search
render :partial => "shared/search"
end
Ok Then add this
in your partial so you can dynamically change your controller for the form
form_tag({controller: controller.controller_name, action: "search_action"}, method: "post", class: "form")
Hi guys thanks in advance for the help. I am building a sort of online game using rails. The user interface is all supposed to be centered around one page: users/... I am running into an issue in creating and interacting with objects outside of users. For example, within the user page users are supposed to have the ability to create a fortress. The fortress of course is its own object with its own model and controller. If I were to try to put a form to create a fort using the form_for tag in the users page, the form wouldn't be able to access the fort controller's #fort instance variable and would throw an error. In my attempt to solve the problem I have created a partial view for forts called _new.html.erb containing the fort form
Here it is:
<h1>Create a New Fort</h1>
<%= form_for(#fort) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :ownership %>
<%= f.text_field :ownership %>
<div style="display:none;">
<%= f.label :xco %>
<%= f.text_field :xco %>
<%= f.label :yco %>
<%= f.text_field :yco %>
<%= f.label :territory %>
<%= f.password_field :territory %>
</div>
<%= f.submit "Create a Fort" %>
<% end %>
I then render that partial in my user show.html.erb here:
<%= render "forts/new" %>
Of course moving the form to a partial does nothing at all, but what I was hoping to do was something along the lines of this:
<%= render partial: "new", object: #fort %>
I would like to pass the fort instance variable into the partial then render the partial in the users view. I recognize however that the variable passed to the partial as described above comes directly from the view the partial is rendered in, and at that realization I am at a loss for ideas.
I have considered the key might be somewhere in associations and I have been crawling the internet for info on that. My models are set up so a user has_many forts and a fort belongs_to a user. I don't know whether or not that will help.
All help is appreciated,
Thanks loads,
Alex P
From your outer view, assuming #fort has been instantiated in your controller, you can pass #fort directly to your partial like this:
<%= render 'forts/new', :fort => #fort %>
I think what you are looking for is accepts_nested_attributes_for. This RailsCast explains how it is used.
In your case you would add accepts_nested_attributes_for :forts to your user model. I'm not sure what your user/show view looks like, but you should just be able to add a <%= f.fields_for :forts do |f| %> which would contain the fields currently in forts/new.
Yes, you can pass Locals with render statements wherever you call partial.
<%= render 'shared/error_messages', :locals => {:info => first, :img_style => "original"} %>
I'm newbie in Rails and I'm developing an app that needs to display a patients info in a form to be updated by a doctor if needed. As soon I can select a patient from a list from sidebar I want to display first just an empty form and when a patient is selected all the info will be displayed on it.
The only way I can guess to do it is to first display the form empty and then, once the patient is selected, catch the patient on the controller and reload the page to allow the form to get the patient info.
Does anybody has a better idea? On negative answer: how can I display an empty form?
Thanks in advance for your time.
Best regards.
Update: This is the form I'm trying to present on the page. #patient is an instance variable that once the page is displayed is not defined yet . It will be displayed once the doctor will select one patient from a list on the side.
<div class="row">
<div class="span6">
<%= render 'shared/error_messages' %>
<div>
<%= form_for(#patient) do |p| %>
<%= text_field_tag 'patient[name][]', nil, :placeholder => "name", :style =>height:12px;font-size:10px;" %>
<%= text_field_tag 'patient[name][]', nil, :placeholder => "surname", :style =>"height:12px;font-size:10px;" %>
<%= p.text_field :email, :placeholder => "email", :style => height:12px;font-size:10px;" %>
<%= p.text_field :phone, :placeholder => "phone", :style => height:12px;font-size:10px;" %>
<%= check_box_tag :active %>
<%= check_box_tag :sex, 'male' %>
<%= check_box_tag :sex, 'female' %>
<%= chack_box_tag :dao %>
<%= p.submit "Sumbit", class: "btn btn-small btn-primary pull-right", id: "boton" %>
<% end %>
</div>
</div>
</div>
An here is the problem. As #patient=nil on the controller since on is selected page crashes.
Thanks again.
What you are describing here are basic controller actions on your model:
Empty Form: #new action on Patients controller
Filled Form: #edit action on Patients controller
Edit: New Strategy to Accomplish Your Proposed UX
Component 1: Nav List of Existing Patients
Iterate over collection of patient objects, outputting a link for each patient to its edit view: link_to patient.name, edit_patient_path(patient)
This nav view will be a partial that you will include in the view templates for the PatientsController #new action and #edit action.
Component 2: Empty Form for Nonexistent/New Patient
In controller new action, instantiate a new Patient object, like so #patient = Patient.new.
Render the patient form on that #patient instance variable, as you do in the view code above.
Include the nav list of existing patients as a view partial.
Component 3: Filled Form for Existing Patient
In controller edit action, instantiate the Patient instance variable, like so #patient = Patient.find(params[:id]).
Render the patient form on that #patient instance variable, as you do in the view code above.
Include the nav list of existing patients as a view partial.
Edit: Old Points on Scaffolding
I would strongly suggest using rails generators and scaffolding to set up basic forms and view templates, at least as an educational pursuit. You will, via the command line, be able to automatically generate the proper controller actions and view templates you are describing above for #new and #edit.
Read this article: http://viget.com/extend/rails-3-generators-scaffolding
Then follow this tutorial: http://railscasts.com/episodes/216-generators-in-rails-3
As you become more comfortable with Rails development, generators and scaffolding will likely not satisfy you and needs for customization. They are, however, a great starting point.
See also: http://guides.rubyonrails.org/getting_started.html#getting-up-and-running
I think, one more option is you can Instantiate your object on your form itself:
<%= form_for(Patient.new) do |p| %>
Thanks
I have a widget for currencies which I use throughout my application. Ie. the user changes the currency from EUR -> USD, or about 13 other currencies. I have a few other use-cases such as dates but this one is the easiest to explain. Currency basically just updates a session variable by calling the currency controller and then uses some JS to reload the page, but I'd like to only fetch certain elements of the page (ie that reflect the currency change and nothing else)...
$("#places_list").html("<%= escape_javascript(render :partial => 'places/list') %>");
or if another controller
$("#locations").html("<%= escape_javascript(render :partial => 'locations/places') %>");
but these elements are specific to the current controller, ie rendering a controller specific partial such as a list... (the currency math itself is in a an application helper, so no new logic is going on), and the currency controller is simple a partial loaded by different controllers. (Locations, Places, etc)
Other than making an action in every controller specific for this purpose, how can I make it behave in a way that I can render elements specific to the current controller, so I can replace them intelligently over js, instead of reloading? Ie. I can pass in to currency the current controller
<%= hidden_field_tag :info, controller.controller_name %>
I'm not sure if any of that makes sense, but I hope it does, at least in my own brain if not in anyone else's.
I have tried a little app and below would be a one solution for you,
first of all, in my case what I'm trying to do is to have an attribute called :info in each model , so that I can call it (<%= f.text_field :info %>) in my views (please note f can be any instance of a model)
for that I need to add :info attribute to each model. You have several ways of doing it
1 - create a class (which inherits from AR::Base and inherit all the other models from the given class) (but it requires some code changes)
2 - Quick and ugly way is to inject my :info attribute to AR::Base class (Which I did ;) )
create a file in config/initializers say curreny.rb and add this code
module ActiveRecord
class Base
attr_accessor :info
end
end
after that from any view which u uses AR, will have the :info attribute
Ex: users/new
New user
<% form_for(#user) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :info %><br />
<%= f.text_field :info %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
<%= link_to 'Back', users_path %>
Please note: this is not a very good solution, but I think with this you can start thinking
cheers
sameera
I would like to create a login field everywhere on the top of my page, so I've add a :
in application.html.erb :
<%= render :partial => 'sessions/new' %>
in .../views/sessions/_new.html.erb
<%= form_tag do %>
<div>
<label for="name">Email :</label>
<%= text_field_tag :name, params[:name] %>
<label for="password">Mot de passe :</label>
<%= password_field_tag :password, params[:password] %>
</div>
<div>
<%= submit_tag "Connection" %>
</div>
</fieldset>
But it's work only if I am in a sessions controller when I test it in my browser,
I think that :
<%= submit_tag "Connection" %>
refers to his current controller (sessions) that's why it's doesn't work in ads/index for exemple but do its job in sessions/index.
What can I do ?
Do I have to specify the controller in the submit_tag ?
Thanks a lot :)
You need to tell the form tag the url that the form should submit to. Maybe by default it submits to the current action or something? You should never rely on the default whatever it is.
Read the api
http://railsbrain.com/api/rails-2.3.2/doc/index.html?a=M002551&name=form_tag
oh and btw the submit tag is just a button, it doesn't have anything to do with why the form does or doesn't work. There's a lot of confusion among rails novices about forms - a lot of people don't really understand how forms work. Before using any rails helpers at all, i'd strongly recommend making your form in pure html. That way you will understand what is actually going on, and the form helpers will be just that, ie "things that help you to do something more quickly" rather than being these magical things that leave you totally clueless when they don't do what you expect.
You need to specify the controller but on the form_tag not the submit_tag
e.g. <%= form_tag :controller => 'sessions', :action => 'new' %>