In an existing codebase, one attribute of the discount model is discount_type. Since there are only 2 types of discounts (percentage and cash) used in this system, they are hardcoded as percentage or cash throughout the system, there is no discount_types table or anything to map to.
In the form, there is the following code:
=form_for #discount do |f|
...
=f.select :discount_type, options_for_select(["percentage", "cash"])
...
This works great for new discounts, but when pulling up the form to edit a discount, percentage is always selected, no matter what the discount object's discount_type is. How do we get the form to default to the discount_type of the object being edited?
Wouldn't simple
= f.select :discount_type, ["percentage", "cash"]
be enough?
Related
I've set in my model('Bambino') a multi-select field to assign a value to the string attribute 'status'. Find the code below from my form partial:
<%= f.select(:status, options_for_select([['segnalato','segnalato'],
['inserito','inserito'],['drop','drop'],['concluso','concluso']])) %>
When I want to edit my record the edit form does not give me back the previous stored value but sets automatically the default value to 'segnalato' (E.g.:if I create a new record setting the status to 'inserito' and after I want to edit the record I get the edit form with the default value of 'segnalato' while I am expecting to see in the field 'inserito').
In this way when you edit a record chances to make a data entry mistake are very high. Why so? Is there a way to retrieve the proper 'status' value that was assigned when the record was created? Thanks
Are you sure that #your_record.status is equal to one of those values? Check it out before any further debugging.
Whilst Andrey Deineko's answer is probably the one you want, there is a better way to achieve what you're doing: enum.
#app/models/bambino.rb
class Bambino < ActiveRecord::Base
enum status: ['segnalato', 'inserito', 'drop', 'concluso']
end
This will give you the ability to use the following:
<%= f.select :color, Banbino.status.to_a.map { |w| [w.humanize, w] } %>
This will store a number for the status, whilst allowing you to define what each number means. It won't do anything about loading a pre-selected object (that's what Andrey's answer will do), but will give you the ability to make your application & select more succinct.
I have three controllers: Users, Courses, and SavedCourses and corresponding models: User, Course, and SavedCourse
The data "flow" is:
Courses are added to the courses table by a sponsor; each course has
14 fields.
A student requests a course by submitting a form with
4 fields - class date, course id, sponsor name, and his / her id.
The input form is in the Views / Users folder and points to the
courses table: form_for(#course). The request is saved and added to
the courses table by the Courses controller.
The incomplete record is matched to complete courses and the 'match' is parsed for
each field's information. That happens in the Courses controller.
The information is passed to a partial (confirmation form) in a
page in the Views / Users folder for confirmation and 'save' as a
record in the saved_courses table.
Between points "3" and "4" something breaks. I suspect my actions are in the wrong controller and / or I'm labeling my fields incorrectly. I'd appreciate another set of eyes on this. Here's the code:
In the Courses controller
Get partial record's information - The information submitted by the student
Def new
new_record = Course.where ... Some fields are null
row = new_record.first
active_date = row.class_date
active_course = row.course_id
active_sponsor = row.sponsor_name
Match on class_date, course_id, and sponsor_name
abc = Course.where .... This works (using foregoing variables as inputs)
Getting values for use in the confirmation form
Still in the Courses controller and new method
#saved_course = SavedCourse.new
#saved_course.class_date = abc.class_date ... etc. for the remaining fields
... etc. for the remaining fields
Everything to this point works in the rails console.
I tried placing the "Def new" code in the SavedCourses controller and it didn't work
The values should be passed to a partial (a confirmation form) that's part of a page in the Views / Users folder:
<%= form_for(#saved_course) do |f| %>
<div>
<li style="list-style-type: none; float: left;">
<%= f.label :class_date %><br/>
<%= f.text_area :class_date, :value => #saved_course.class_date, autofocus: true %>
</li>
</div>
... followed by more fields
Unfortunately, the form renders with blank / empty fields rather than fields with the #saved_course information. I, incidentally, tried it with and without autofocus. I'd like to enable editing by the student, so I left the fields as text-area with autofocus.
There are no errors being reported by the server, console.log, or rails console.
Thank you in advance for your help.
After digging around some more and re-phrasing my question, I discovered nesting. Here's a link to a previous Stackoverflow answer Creating nested models: Creating nested models - Rails 3.1 Also, look at Ryan Bates Railscasts #196 and #197, Nested Model Form: http://railscasts.com/episodes/196-nested-model-form-part-1? (The link is for the first one, #196.)
I have another form_for select question.
I'm using a partial for my new and edit form for my Customer model. The :customer_type can be one of three values: Contractor, Business, Homeowner. So, I put these values in an array in my model.
def self.customer_types
customer_types = ['Contractor', 'Homeowner', 'Business']
end
In my form I do this:
<%= f.select(:customer_type, options_for_select(Customer.customer_types)) %>
This works fine in the new form, but on the edit form, how do I get the selected value for :customer_type to be selected? I've tried several things but nothing works for me.
Thanks for any tips.
-jc
options_for_select takes an optional second argument, which is the selected option :)
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-options_for_select
The second thing you need is the actual value, which can be accessed via f.object. So something along those lines
<%= f.select(:customer_type, options_for_select(Customer.customer_types, f.object.customer_type)) %>
I am new to rails, but not to programming or databases.
A BETTER PHRASING OF MY QUESTION IS IN MY ANSWER BELOW.
For simplicity in this example, I have 3 models:
User
Subscription
Default_Subscription
User has_many Subscriptions
Subscription belongs_to User
Default_Subscription has_many Subscriptions
Subscription belongs_to Default_Subscription
Default_Subscription is a pre-populated table with certain types of subscriptions.
During the subscription process, the default subscriptions are listed at one point, and there
is a quantity box alongside each one.
The user enters the quantities for each subscription and hits submit to continue on.
My question is:
How would one go about creating a new subscription for each quantity in a number form?
So you would have a list something like so:
<ol>
<%= each subscription with quantity box %>
</ol>
<%= button_to %>
When the user hits the button, how do you add up the quantity from each box and add a new subscription for each one? Do I have to use javascript to get the numbers? Do I somehow use rails forms even though this quantities are not associated with any specific database field? Any recommendations or pointing me in the right direction to figure this out on my own would be great.
This form box IS NOT A FIELD FOR ANY MODEL, it's a count for an association. Let me rephrase: Each quantity in the form boxes represent the number of NEW Subscriptions to be created. Each of these subscriptions BELONGS_TO 1 DEFAULT_SUBSCRIPTION. In essence, the number represents the number of new subscriptions ASSOCIATED WITH THAT DEFAULT SUBSCRIPTION.
I'm using rails 3.2.1, and ruby 1.8.7
Thank you
Not sure I totally understand your description, but I'll take a shot.
Use the 'form_for' function to build your form, based on an instance of #default_subscription (established in the "new" action in your controller). If there are default values in #default_subscription, will show in the fields and the user can change them as they see fit. (this assumes your DefaultSubscription model has three attributes: sub1, sub2 and sub3.)
<%= form_for #default_subscription do |f|
<%= f.label :sub1 %><br />
<%= f.number_field :sub1 %>
<%= f.label :sub2 %><br />
<%= f.number_field :sub2 %>
<%= f.label :sub3 %><br />
<%= f.number_field :sub3 %>
<% end %>
When the user clicks the submit button the contents of the form with we assembled into a hash and passed into your controller's "update" action via params[]. You can extract the subscription hash like this:
user_subscription = params[:default_subscription]
At this point you have all the numbers that the user entered into the fields in the user_subscription hash. You can now parse the hash to extract the numbers, do your math, and then create the appropriate subscriptions per the user's input. (one note: the numbers could be strings and you might need to convert them back to integers as I've shown below.)
For example, to total all the subscription values and save that total into a user's subscription:
total = 0;
user_subscription.each do |key, value|
total += value.to_i
end
new_sub = current_user.subscription.new
new_sub.total = total
new_but.save
As I said, I don't understand your description clearly, so this might not be germane, but hope it is close to what you were looking for.
Good luck.
I have figured out one way, and reading my original post again, the whole thing is really confusing because I didn't know how to say exactly what I was trying to accomplish. I must say a lot of the reason I was confused is because the form I wanted did not correspond to any model, just an association count, which is ultimately a basic html form if you want to create a bunch of new objects without having their attributes yet. I'll first clarify then show my solution.
Clarification:
I have 2 Tables:
Subscription
Default_Subscription (Pre-Populated)
Subscription belongs_to Default_Subscriptions
Default_Subscription has_many Subscriptions
A User is subscribing to my website. This process is a step by step: not everything happens on the same page.
This all happens in a subscribe_controller. Each action corresponds to a step in the process.
One of the actions is default_subscriptions. This action lists the Default_Subscriptions a User can choose from, except they do not just choose, they can enter an amount for each type of Default_Subscription they'd like.
When the Default_Subscriptions are listed on the default_subscriptions page, I wanted a form with an html number input alongside each of these Default_Subscription. When the form is submitted via a next button, I had no idea how to gather the quantities from each html input and create an array of Subscription.new, with each Subscription's default_subscription_id corresponding to the proper Default_Subscription.
One Possible Solution:
def default_subscriptions
#def_subscriptions = Default_Subscription.all
end
Lets say the page I want proceed to after all the quantities are entered on the default_subscriptions page is review_subscriptions.
Here's what I did to create the proper form to proceed to the next action in the controller:
<%= form_tag( {:controller => 'subscribe', :action => 'review_subscriptions'}, :method => 'post' ) do %>
<ol>
<% #def_subscriptions.each do |ds| %>
<li>
<%= ds.name + ' ' %>
<%= number_field_tag("subscription_counts[#{ds.id}]") %>
</li>
<% end %>
</ol>
<%= submit_tag('Next') %>
<% end %>
The trick here is that string passed to the number_field_tag. By placing a single set of square brackets at the end of the string for a field_tag method parameter, the part before the brackets is the name of the hash, and the thing in the brackets is a key in the hash, and the submit button causes the corresponding value for each key to be the value of the field. Pretty cool!
The parameters passed to the next action would contain a hash called subscription_counts, and iterating through this hash would give a corresponding new subscription amount for each default_subscription_id. Like so:
def review_subscriptions
subscription_counts = params[:subscription_counts]
subscription_counts.each do |id, amount|
counter = Integer(amount)
until counter == 0
new_subscription = Subscription.new
new_subscription.default_subscription_id = Integer(id)
#subscriptions << new_subscription # #subscriptions is an instance variable
counter -= 1
end
end
end
I'd just like to point out, the more I work with them, the more I love them; I love Rails, and I love Ruby. They are super fun and classy. An until loop... how cool is that? If you have other solutions, now that my question is more obvious, please chime in! I know others out there are trying to find some slick ways to create multiple new objects in a one to many association with a single post call like this. Technically my objects aren't saved in the database yet, but that wouldn't be to hard now.
The main reference which helped me the most in reaching this solution was:
http://guides.rubyonrails.org/form_helpers.html
If you are new to rails, and confused about forms, read this. I feel like a master now. Rails devs are really good at documenting things!
I would like to know which way is the best to resolve my question :
I have a form in order to select people via a select field. If the name is missing in the select field, a text field is available to add directly the person's name.
- The form in new.html.erb is the format of the new action of the Team controller.
- The list of the people is extracted from the People model.
def new
#team = Team.new
#people = People.all
end
I created an attribute in the Team model to store the new_person text field :
class Team < ActiveRecord::Base
attr_accessor :new_person
...
end
Finally, here's an extract of my view :
<%= f.select :person_id, #people.map { |p| [p.name, p.id] } %>
<%= f.text_field :new_person %>
Obviously, I would like to save the new person in the table Person before saving the data from the form. As usual, the id are saved instead of the names
At this point, I've got two issues :
1/ The params array has the key new_person what doesn't have the table. So it is not possible to use the Team.new(params[:team]) method. Does exist an easy solution to avoid this problem ?
2/ As I need the person_id, how can I get it when the name comes from the new_person field? In using the before_filter method ?
Thanks a lot,
Camille.
1) You should consider using fields_for in your view within your form_for block. This will allow you to specify that the fields within the fields_for block are attributes of a different model, will generate the appropriately named input fields, and allow you to use params[:team] in your controller. See the FormHelper documentation for more on this.
2) While you could do something in your controller to first check for a value in the new_person field, create the record, update the contents of params[:team] with the value of the newly created person and create the team, this feels a bit like a hack to me. Another possible solution which may be less fragile would be to use some JavaScript on the page that would render some kind of modal dialog for the user to create the new person, submit the new person to the person#create controller method, then refresh your drop down. It would probably not be terribly difficult to do this using a jQuery UI modal form (very good example at that link to do what you need) with Rails remote form and unobtrusive JavaScript.
This is probably a more difficult solution to your second question than you are hoping for, but probably more useful in the long run.