Best way to save the model to use later as "template" - ruby-on-rails

I don't know if template is the right word for this.
I want models which has template boolean true, to be choose-able at the same models form view. And on choose it would fill the form with the chosen models values.
I'm thinking about this solution:
List the models next to he form which has the template attribute set to true.
On click load it trough AJAX , and fill the form with the loaded attributes trough javascript.
I'm wondering if there is a better way for this?
Edit.:
Sorry if it wasn't understandable.
Model.rb has boolean attribute :template.
If template is set to true. It is displayed on the form view of the Model.
_form.html.haml:
:collection_select Model.where(:template => true)
and on select, the template model fills, in the new Model's attributes, with the old template Model's attributes.
I would like to find the Rails way for this.

Add a class method in your model to find the template record.
def self.find_template_record
template = where(template: true).first
raise "no template found" if template.nil?
return template
end
In your controller, load the template record and clone it. Don't use dup because that will copy the id.
def new
#model = Model.find_template_record.clone
end

To duplicate an ActiveRecord model, use its dup method:
#model = #template_model.dup # create the base
#model.attributes = params[:model] # override particular attributes

Related

Append form partial in the new view of the same model in rails

i'd like to use the same model to create in one view (new.erb.html) more records at once with a single submit.
for example I've a model called Report with some fields such title, description and date
how can render same form partial many times when i click an add button? i think is not a nasted model's problem because is always the same model actions.
Thanks
You can do something like this (I haven't test the code myself):
haml:
.model
%input{:name => "model[][name]"}
%input{:name => "model[][desc]"}
%input{:name => "model[][date]"}
.container
%button.add-model
js:
$('.add-model').click(function(){
$('.model').clone().first().appendTo('.container');
})
controller:
def save
params[:model].each do |props|
Model.create(props)
end
end
What I do is using JavaScript (jQuery) - on page load I save the only rendered form into JS variable (actually not the form, but the inputs inside it), and then on clicking "Add more" link append more inputs into the form.
And to save many objects at once you will need handcrafted input names (something like model[][name] in order to send an array of values), as well as controller that accepts array.

Rails form redirecting to 'new' action

What I am trying to do is build a form in which the user fills some of the fields for a new Publication, and takes you to the New Publication action, with those fields already filled in, so the user fills the rest.
I got the controller part covered, but I cant find how to use form_for for this, as its not exactly associated to the model (only some of the necessary fields are in the first form).
you could do
form_tag new_publication_path()
Not necessarily the best way to do this, but you can hide some of the fields in the form depending on whether the model id is valid. For example (in haml):
- if #model.id #only shows up if the model has been saved.
= f.text_field :field_name, ...
This way you can use the usual new, and then when the model has been saved, just redirect to the 'edit' action and the rest of the fields show up.

check_box manually set to ticked through controller

In my index controller I have a bit of logic. Occasionally, I want to set the check_box default to ticked when the page renders.
To do this, I want to pass a param to the view and get the check_box to use this param (true/false) to determine whether to show as ticked or un-ticked.
Can I do this?
What I would do is this:
Let's say to your index page you are passing a param q.
So the url is: website.com/foo?q=true
The symbol / field that the checkbox controls for the model Model is :bar
In your controller, try something like this (EDITED WITH #Mike's suggestion):
def index
#model = Model.new
#model.bar = (params[:q] == "true")
end
See if that works. I don't think you'll need any extra logic in your view.

Submitting custom information to a controller

This is probably simple, but I've tried a few things and couldn't find a way to make it work.
I would like to update a model with custom information given in a form_for
To make it more concrete, I'm on the show page for a particular instance of MyClass and I would like to pass something like the string "yay" into the controller, and then do as I please with the input. Maybe pass it back to the page as a flash message, or maybe modify the contents and then store it as a field of the MyClass instance.
I can write form_for's that contain the attributes of MyClass without prbolems, but it seems that other fields throw an error.
How do I write the form_for so that I can accomplish one of the two above scenarios?
def update
#my_class = MyClass.find(params[:id])
flash[:notice] = "This works" # but what can I write in a form for for it to be a variable that's passed in?
#rest of the update
end
Form helpers that unitize a form builder instance (like f.text_field) expect a valid model attribute so it can generate the appropriate id and populate the field with data from the model. If you want to have form fields that do not correspond to model attributes, don't use the the standard f.text_field but instead use:
<%= text_field_tag 'my_custom_tag' %>
which should render something like:
<input type="text" id="my_custom_tag"></input>
When the form is submitted, the value of the input will show up in the params hash with a key of :my_custom_tag.
I hope this helps.
It seems that you would probably need a hidden_field in your form :
http://apidock.com/rails/ActionView/Helpers/FormHelper/hidden_field
However, if you wish to save some kind of state, which seems like this is what you want, you would never use that. Instead, you would use a session. The reason is that a hidden field can be manipulated by the client and thus security can easily be overridden.
Like Spyros said, a hidden field will give you the place. Assuming you are ok with the fact that a user can modify the URL, just add attr_accessor :foo to your model.
In the controller you can access it with bar = params[:foo] and do as you please.

Groupon Alert Rails

I am new to rails so please be patient. I am open to suggestions on how to do this differently.
I would like to render 2 separate controller actions in one layout in rails.
I have 2 controllers: Coupons, and MainAlert. In the body of my application wide layout page I have a <yield > which loads the index action of Coupons or MainAlerts depending on the request (e.i. localhost/coupons or localhost/MainAlerts).
However, I would like to load the index action of Coupons or MainAlert or other controller (depending on request) but ALWAYS load the _form(where user creates new alert) at the very top on a I will hide and show.
"Get deals by email (+)" option at groupon.com
How do I load both controller action (index from Coupons and the _form (new? create?) from MainAlerts in the layout. The values of the MainAlert form need to be save to the DB if user hits submit.
I am open to suggestions on how to do this differently.
Thank you for you time everyone. =)
I'm kind of a newbie too, so expect more nifty answers.
But one way to solve this would be to use an before_filter in the Application Controller to always set up a new MainCoupon instance variable as every action is serviced. After that you could use render 'maincoupon/form' to render the form in the layout. The form should work as intended because the need instance variable was set up by the before_filter.
It could look something like this:
# application_controller.rb
class ApplicationController < ActionController::Base
# other stuff
before_filter :new_coupon
# other stuff
def new_coupon
#maincoupon = MainCoupon.new
end
end
In the layout you could have
<% = render 'maincoupons/form' %>
Or better yet, using HAML, just:
= render 'maincoupons/form'
In general your new action is associated with a view where the user enters information into a form. The new action in the controller creates a new object #maincoupon = MainCoupon.new of the desired to type, which is used as a "scaffold" for building the form.
When the user submits, the form information is packaged sent as a parameter to the create action, which takes the information sent from the form and uses it to create a new object of the desired type.
#maincoupon = MainCoupon.new(params[:maincoupon])
After that it uses the #maincoupon.save method to save it the to the database.
You can try the corresponding model methods out yourself in the console (rails console).
For example:
> A = User.new
Would create a new user, but doesn't save it to the db.
You could continue like this:
> A.name = "Apa"
> A.save
This will create and save it straight away.
> User.create(:name => "Apa")

Resources