One form to update multiple pages in Rails - ruby-on-rails

Fairly new to Rails. I'm trying to create a form that updates two models, and outputs to two separate show pages. One, is this possible, and two, how? I saw a lot of posts about one form being able to update multiple models, but not sure if I can have one form that creates two separate pages.
edit:
Thanks for the comments so far. And, sorry for the lack of clarity. basically I have two models. One is for a "Course preview" page. And the second is for the "Actual Course". Any user can view the Preview page, but will have to purchase the course to be allowed to view the course page.
What I am trying to do is use 1 form to create the "course preview" and the "course" at the same time.
Thanks in Advance!

You can't render two pages at once, a user can only see one page at a time.
But you can create one page that displays the results with some clever coding. If you have two models, say Model1 and Model2, and a view for each one, say model1/show.html.erb, you can change the show.html.erb code from:
<%= #model.name %>
etc...
to
<%= render 'display' %>
Create a file named _display.html.erb, and put the contents from show.html.erb in there. Now, when you visit the show page for Model1, it will call the display partial and render all the information accordingly. Lather, rinse, repeat for Model2.
So, your return page for your dual form would also utilize this very same partial. The results page for your form would look like:
<%= render 'model1/display' %>
<%= render 'model2/display' %>
This pulls the partials for each model type and puts it in the results page.
For more information on using partials, see:
http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

Related

Is there a way two have two different index views on the same controller?

I have a situation where I want to set up two different index views from the same controller.
The default view has a table with columns pertaining to incoming stock, while the second one has a table with columns pertaining to the billing for those incoming stock orders.
This separation is to de-clutter the one view I have now that shows all the information on one page.
I plan to switch between them with a button on each view leading to the other.
I realize this is probably not the Rails Way, and if there is such a way to approach this, I'm all ears.
I thought that I could do this using Variants but it seems to me that only works for displaying content to different device types.
I can't understand what you want to achieve ?
If you really want to set up 2 index views, you could do :
def index
if params[:view]
render 'one_page'
else
render 'another_page'
end
end
You could replace param name with what you want.
And when you click on your button to change page, you may do
config/routes.rb
resources :products
index.html.erb
<%= link_to 'Next', products_path(view: true) %>
That's an option, but I may give you a better answer if I understand better.

Render a form in a modal(bootstrap) and make it available on another controller's view

It's been a while since I've used Rails and I think I've gotten a little rusty. Is there a way to do this?
I'm trying to make a messaging feature that allows one user type to message another. I want the button to display on the User index page and the user show page. When the button is clicked a modal will popup with a form contained therein.
Currently I've made a Message model with three columns: user_type1_id, user_type2_id and message_body.
Should I make a distinct controller for this new model? Or should I put the logic in the controller of user_type1 (the usertype that will be messaged)?
Any other suggestions would be welcome.
Controllers are there primarily to get data from the database and get it ready for the views. So if you have user#index and user#show pages, then you should use the UsersController for all the logic associated with those views, even though it uses other modals. It really is the "Rails Way". If, however, you were to create a message#index page, then you should create the associated MessagesController.
Also, there is nothing wrong with creating a partial and sticking in the messages view directory (the filename would be, say, messages/_form.html.erb). Then, whenever you needed that form (throughout the entire site), all you would need to do was type:
<%= render 'messages/form' %>

where to place my forms to follow 'DRY'

I am working on a larger application and I see that I end up repeating the same forms twice etc.
For example when you register and on edit account one is in the #new and the other is in the #edit. I'm assuming this is bad practice and it also takes up a lot of space in the view. How do I gather these forms and then just display them on both pages?
If you use the rails generators they normally create a structure like so:
edit.html.erb
new.html.erb
_form.html.erb
Both new and edit pages render the form partial like so:
<%= render 'form' %>
This keeps the code dry so long as your form is the same for editing and creating.
All partial file names begin with an underscore, and if you want a partial to be available across your whole application put it in views/shared.
Some reading on partials.

Allows user to edit pages that contain variables [duplicate]

This question already has an answer here:
How to render a string as an erb file?
(1 answer)
Closed 9 years ago.
I have some editable pages that are stored as text in my database. These pages will be called in my view like...
#app/views/static_pages/scheduling_text.html.erb
<%= Page.find_by_name("New Registration").content %>
Page.content is of type 'text' (not string). A portion of the text that contains variables would look like...
You have successfully registered for New Student Orientation on #{<%= #registration.orientation.class_date %>} at...
If course when I call this content in the view, I just get the text, not the model values. How can I make these pages access the model values? I also tried adding #{} around the text without success.
This seems to be a duplicate of Rails: storing erb templates in database
Given that, this should do the trick for you, or at least be close enough to get you started:
<%= sanitize ERB.new(Page.find_by_name("New Registration").content).run %>
Additionally, you can remove the sanitize if content is not user-supplied (this is primarily a security concern).
I've done something exactly like this using HAML processing:
= sanitize Haml::Engine.new(article.content).render
For reference, here's the appropriate ERB documentation: http://ruby-doc.org/stdlib-2.0.0/libdoc/erb/rdoc/ERB.html
OK, after much wailing and gnashing of teeth here is the the solution I cam up with. First I am using mustache. This is much safer than storing erb in the templates and prevents malicious injection of sql into your app. I simply added 'mustache' to my gemfile rather than mustache-rails as it seems to be more up to date. I then created a simple Page model with two attributes: :name and :content. I am using the page model to store the raw mustache code.
Here are the relevant files...
In my controller I call...
#app/controllers/registrations_controller.rb
def create
#registration = Registration.new(params[:registration])
respond_to do |format|
if #registration.save
if #registration.orientation != nil
format.html { render "scheduling_text.html.erb" }
Then my view looks like...
#app/views/registrations/scheduling_text.html.erb
<%= Mustache.render(Page.find_by_name("New Registration").content, {:registration => #registration }).html_safe %>
<%= link_to 'Back', orientations_path %>
...
Then in my page model I have something like...
You have successfully registered for New Student Orientation on {{ registration.orientation.class_date }} at {{ registration.orientation.class_time}}. Please arrive 10 minutes prior to your scheduled Orientation. Remember, you must attend this Orientation session before you may register for classes. ...
Using a page model with scaffolding like this works well because it gives you the new, update, and create actions that will allow users to edit content. Note, they can easily mess up your ruby variables, so thats the downside. Just let your users know to not munk with anything that is between {{}}.
Hope this helps someone else out.

How to selectively display fields in new/edit views with custom form builder in rails 3.2.12?

In our rails 3.2.12 app, we would like to selectively display fields in new/edit views (using simple_form) based on the access rules. For example, for sales, only customer's name and phone# can be displayed. Since we don't know what the access rule is going to be, we need to dynamically construct the view at run time. One way to accomplish this is to use if in the views and this would make views messy. We thought customform build might help. After reading a few posts online about custom form builder, we still did not have much clue. Can someone provide details about how to implement this with customform builder? Thanks for help!
UPDATE:
Since we don't know what the access rule is going to be, we need to dynamically construct view at run time.
Usually a custom form builder is used to change the structure of the form's HTML more than to control field access.
A couple of suggestions to "clean up" the views:
Using SimpleForm will let you handle form fields/labels as a unit, making it easier to exclude a field using only something like = form_builder.input :credit_card_number if current_user.admin?.
For a more application-wide solution CanCan can help you manage authorization and roles.
Edit:
Based on your comments, it sounds like the following could be a good approach for you if all the columns are treated the same and you don't need to change their order (using HAML, but you could change it to ERB if necessary):
= simple_form_for #model do |f|
= f.error_notification
- #model.columns_available_for(current_user).each do |column|
= f.input column
You can use rails helpers to do that.
For ex.
module SalesHelper
def show_fields
if current_user.admin?
render 'some_partial' #having name and phone field
else
render 'other_partial'
end
end
end
In your views add respective partials and from new or edit just call
<%= show_fields %>

Resources