#57 Create Model Through Text Field
Let's say you provide a select menu for setting which category a given product belongs to, but you also want the option of creating a new category by typing the name in a text field. See a great way to do that in this episode.
Hey, thanks. Great tip.
Tried this with tests :P.
http://pastie.caboo.se/78522
Thanks again Ryan. Your tip is sure to save me some time. I'll definately be looking into 'collection_select', and it's advantages.
Thanks again
Hey Ryan, great stuff as always.
Could you do a part-two on this where you disallow the selection of an existing category and entering a new category name at the same time?
Perhaps adding an "other" field to the pulldown menu which dynamically makes the "create one" field fade in to the page? (and selecting an existing category again makes it fade out)
Thanks.
This is freaking awesome!
I have to agree that adding some AJAX voodoo to this screencast would make an excellent Part 2
You don't need AJAX voodoo...
This is just a related example, but the idea is the same from the view side.
<label for="occurs">Occurs:</label><br />
<%= f.select(:occurs, ["Once", "Daily", "Weekly"], {}, :class => 'smallTextInput', :onchange => 'Form.displayOccurs();') %>
<span id="occursbox" style="display: none;">for <%= f.text_field :quantity, :class => "tinyInput" %> <span id="timeframe"></span></span>
Form={
displayOccurs:function() {
occurs = $('event_occurs').value;
switch (occurs) {
case "Once":
$('occursbox').hide();
break;
case "Daily":
$('timeframe').update("days");
$('occursbox').show();
break;
case "Weekly":
$('timeframe').update("weeks");
$('occursbox').show();
break;
}
}
Hi!
Dunno if you also do audience requests, but here's mine:
I'd really like to see a screencast on backgroundrb/druby combined with rails.
great site, you rock.
I understand how the new category is created, what I don't see is how the DVD Player is associated to the new category.
Any insight?
oh... guess i'd need to see the controller for that part... wasn't thinking.
@ron, actually the controller doesn't know anything about the Category model - it only creates the Product model. The association is set by using the "create_category" method. This is provided by the belongs_to association and automatically sets the category to that product when it is created.
Great, Ryan. Thanks.
Could you explain the difference between build_category and create_category? The api docs don't seem to help me much.
@ron, build_category is like Category.new, it doesn't save it to the database. creat_category is like Category.create, it saves it to the database.
great stuff Ryan,
I don't see a link on the website for submitting requests, but is it possible to show how to simulate a treeview type control in Rails.
Thanks!!!
This is great for simple models, but does it expand well for more complex models?
How many fields is this wise to do with before you should consider a fields_for option?
Great episode
How about the other way around. When I create a category I would like to create a couple of products belonging to that category as well. I've realised there is something like category.products.create but I dont know how to use it. Any pointers?
Thanks
First of all THANK YOU for your great work !!!
There is one thing I can't understand in your sample:
In the view I use " text_field 'form', 'id' "...
what is " f.text_field 'id' " instead?
@JT, I wouldn't use this technique if you have to fill in more than one attribute for the related model. That can get pretty messy in the code. Instead, fields_for seems like a better solution that way you can group it in a second hash and not have to create a virtual attribute for every related attribute. Maybe I'll make a screencast on this in the future.
@Oskar, this is on my todo list for a future episode. :)
@Ioribox, That "f" variable is a form builder which was created through form_for. I'm just passing it as a local variable to the partial which is why you don't see the form_for statement.
Thank you so much for your replay!
About this episode: I've added the "Create Model Through Text Field" into
one of my test projects. It's been fast and simple thanks to your tutorial !
I've just modified the callback function to check the uniqueness of the new
record!
def create_new_category_from_name
unless new_category_name.blank?
if category = Category.find(:first, :conditions => {:name => new_category_name}) then
self.category_id = category
else
create_category(:name => new_category_name)
end
end
end
THANK YOU AGAIN
@LoriBox, as an alternative you can use find_or_create_by_name method:
http://pastie.caboo.se/79856
Editing a product doesn't seem to allow the creation of a new category, only creating a new product. I followed the implementation given in the screencast fairly closely, so do you think you could offer a guess as to what might be going wrong? Cheers.
@Benedict, check the code inside of the Product model. Make sure you set the callback up so it creates a Category model when it is saved.
I realised I had a required field in the Category model which wasn't being passed a value, fixing that sorted it out. Thanks for the help though.
I noticed that using the create_category method doesn't run the validations in the related model "category.rb" Is there a good way around this or do we need to redo our validation checks in the method like LoRiBoX's comment above. I'm sure there is a DRYer way to do it but I'm not sure how.
Hi Ryan. First of all, thanks for the excellent Railcast-episodes! They really help finding my way through.
I'm finding the title of this episode misleading, but maybe I don't understand things well enough just yet. Anyhow, imho we're not creating models but records, so I'd call the episode "Create record through text field".
cheers from the nitpicking-department
Ryan, what about some validation examples? For example, I'm validating for :company_id given one of the companies from the drop-down are selected, however, I don't want to run the validation if new_company_name is present. This doesn't seem to work:
validates_presence_of :company_id, :unless => new_company_name?
Any ideas why?
Cheers, GREAT tutorials mate, keep it up! : )
Try this (note the quotes around the condition):
validates_presence_of :company_id, :if => "new_company_name.blank?"
Has anyone did this using an auto complete instead of a select and text box. I was hoping to add the feature where the user would start typing a name, if it was in the list it would add it if not it would create a new one.
i want code for particlur limit of values maintain in textfield
I'm using rails 2.0.2. The params hash *does* have the value that I'm passing through the form, however the attr_accessor that I created is *not* getting populated. I am having to explicitly set the value of attr_accessor from the params hash.
Any thoughts?
I realized I am using attr_accessible - got to remember to add the virtual attribute to the list.
Also re: LoriBox's approach you might want to alter the conditions as such:
:conditions => ['lower(name) like ?', new_category_name.downcase ]
just a thought...
Just what i was looking for!
Once I implemented this, I now do not get redirected to the correct page after submit. Should i put the redirect page path into the model def?
Ryan thanks for shedding some rails light to my noob darkness. I have a problem with :category_id. I get the "undefined method" error. I read the collection_select api for rails 3 and it doesn't seem I'm doint anything wrong. Yet I still get the error message. I'm using this:
<%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => true%>
I just want to add a category to each product but I get this annoying error.
PS: Category and Product are both generated with scaffold.
Thank you again for your time and the great Rails screencasts. Kudos man.
Does anyone know why I would be getting an error that says, I can't leave the selection field blank. here's the code I put in the items\_form.html.erb:
<p>
<%= f.label :Category %><br />
<%= f.collection_select :categorry_id, Categorry.find(:all), :id, :name, :prompt => "Select A Category" %>
or create one:
<%= f.text_field :new_categorry_name %>
and the code i placed in the model.
attr_accessor :new_categorry_name
before_save :create_categorry_from_name
def create_categorry_from_name
CreateCategorries(:name => new_categorry_name) unless new_categorry_name.blank?
end
however when I try to create an entity it wont allow it. it's says I cant leave it blank. Any suggestions?
I'd really like to see a screencast on backgroundrb/druby combined with rails.
Does the example still show how one would do this with Rails3?
In case it helps anyone else, I believe the the favored way of doing this in Rails 3+ is with the method "accepts_nested_attributes_for".
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
I ran in to the following issue
with <%= f.collection_select :category_id, Category.find(:all), :id, :name, :prompt => "Select a Category" %>
we let user not to choose category_id, but use can also not type into create category field - so we let user to create product without category
if i add validation on cateory_id it did not save
I get the following error when calling
create_project
:undefined method 'create_project' for #<Project:0x104eb03c0>
shouldn't i get the create_association(attributes = {}) method for free in a belongs_to relationship?
thanks in advance, cole
This episode has been updated for Rails 5 as a blog post. Create Model Through Text Field in Rails 5