I'm developing a simple rails app where I want to plot some stock charts. The problem is that when I start my server and load localhost the default value/ticker symbol is not loading which means that I have to type in a ticker in my form for it to work.
I found this thread where I learnt how to write a default value in my form/view, like so:
<%= form_for :find_it do |f| %>
Ticker symbol: <%= f.text_field :string, :value => "JPM" %></br>
<%= f.submit "Find" %>
<% end %>
and that's all fine, but it does not submit the value by default.
So how do I go about fixing this and what is the best practice?
In your input field you have list your attribute as a string, while that is the type, it most likely isn't the actual name of the attribute you wish to save "JPM". So you should change
<%= f.text_field :string, :value => "JPM" %>
to
<%= f.text_field :attribute_name, :value => "JPM" %>
If I copy and paste your form into a Rails app on my machine it does display a text field populated with "JPM", which I believe is correct.
When you hit submit the form will post to a create action with params containing:
"find_it"=>{
"string"=>"JPM"
}
Another thing I noticed is that you have f.text_field :string. This should be the name of your attribute, rather than the type (i'm assuming that you don't have a field called string).
Related
I'm trying to submit a RoR Form. Strong Params are fine as I'm not getting a not permitted message in the logs. For some reason, I keep getting a this field cannot be blank error message for the below field. The logs say the client_name field is blank even though I've selected something. There's a has-many/belongs-to relationship between designer & client-folder.
When I choose one of the existing client_folder from the dropdown and press submit, it gives the error message. If I use a text field and simply type a name, it works fine, so I believe it's just something with collection_select. Where am I going wrong?
<%= form_for([#designer, #client_folder]) do |f| %>
<%= f.collection_select :client_name, current_designer.client_folders, :id, :client_name, {}, {id: "existing-list", required: true} %>
<%= f.submit "Create" %>
<% end %>
I'm building a page that contains a html table, where the user can choose the name in the table header and the content in the table row.
The user will enter the information to a form, which will be parsed into a hash and saved into the DB.
Here is an example where :key will be a key of the hash (table header text) and :value will be a value in the hash (table column content).
<%= form_for([#page]) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.text_field :key1 %>
<%= f.text_field :value1 %>
<%= f.text_field :key2 %>
<%= f.text_field :value2 %>
<%= f.text_field :key3 %>
<%= f.text_field :value3 %>
<%= f.text_field :key4 %>
<%= f.text_field :value4 %>
<%= f.submit "Save" %>
<% end %>
I could make a new DB table with a has_many association to the page DB and have the info stored in that table. Then that data can be rebuilt into a hash when I need to render the view.
But if I could save the entire hash into a column in the page DB, then it would save me from having to rebuild the hash every time someone visits the page.
I'm struggling to come up with how to do this in form_for.
The first issue is that it requires key and value columns in the page table. A simple fix would be change all inputs into <%= f.text_field :html_table %> (for html_table column in the page table). But then it won't be able to distinguish between a key and a value in the hash. And I also don't have any way of telling it to put the info together into a hash that is then stored into the page table's html_table column.
Not sure if this is even a possible thing but it doesn't hurt to ask before I go ahead with building the has_many association table and setting it up that way.
I'm rather confused about your question.
Can't you build a hash like this in your controller action?
html_table = {
params[:key1] => params[:value1],
params[:key2] => params[:value2],
params[:key3] => params[:value3],
params[:key4] => params[:value4]
}
Then save it to #page.html_table attribute.
EDIT:
In this case, the form is not about attirbutes of a particular object. So instead of using form_for (Link), you should be using form_tag (Link).
Example:
<%= form_tag "/pages_controller/build_html_table" do %>
<%= text_field_tag "key1" %>
<%= text_field_tag "value1" %>
<%= submit_tag "Save" %>
<% end %>
I have a controller named Welcome with view called index.
In my index view i have created a small form as such.
<%= form_for :location do |f| %>
<%= f.label :Longitude %><br>
<%= f.text_field :integer %>
<br>
<br>
<%= f.label :Latitude %><br>
<%= f.text_field :integer %>
<p>
<%= f.submit %>
</p>
<% end %>
In this form the user can enter some integer value for longitude and latitude. Once the user enters value for longitude and latitude. They click submit. Upon submit i would like to store these values in my controller. So i am using the following method where i have two instance variables taking values from the form.
def index
#long = params[:longitude]
#lat = params[:latitude]
end
In my routes.rb I have
get 'welcome/index'
post 'welcome/index'
Please tell me where i went wrong. Also if someone can suggest a better way of doing this also i would appreciate it i am new to rails and i want to learn the correct way of doing things so i don't create bad habits early on.
The reason it's not working is because your fields are both named :integer, and since they share the same name, the browser will only send one value.
So, with your code, if you filled in the first field with 'a' and the second with 'b', your params would contain something like this:
{ location: { integer: "aaa" } }
Which obviously isn't what you want! If your HTML looked more like this (I've stripped the layout stuff to make things clearer):
<%= form_for :location do |f| %>
<%= f.label :longitude %>
<%= f.text_field :longitude %>
<%= f.label :latitude %>
<%= f.text_field :latitude %>
<%= f.submit %>
<% end %>
Then you could access the params in your controller params[:location][:longitude] and params[:location][:latitude]
A good idea to see the difference between the effect of your form vs this form would be to inspect the html. Take a look at the input name attributes, and label for attributes and see how they match up with the params Rails receives. Also, when you post the form, be sure to look in your server log to see the params! :)
After reading your question, I think you want to see how controllers, views and models work. For learning purpose you can generate scaffold and study the generated code.
For example, generate a model GeoLocation, related controller and views by this:
rails g scaffold GeoLocation longitude:string latitude:string
Now fire up rails server and browse http://localhost:3000/geo_locations/new and save your long, lat. I wrote this answer to give you some guidance.
You can follow these excellent books:
The book of Ruby
The Rails 4 Way
I am useing a form_for helper to collect data on the client side of my application. However something weird is happening. I am not collecting the :name and :description and they are both returning as nil. this is my code:
<%= form_for #type do |f| %>
....
<%= f.text_field :name, :class => "col-xs-4" %>
<%= f.text_field :description, :class => "col-xs-4" %>
<%= f.submit %>
....
Do I need to make a fields_for under the form_for to get this working? It is a bit tricky because I am using #type which in this case is set up to tell the view which kind of attr. they are looking at. For example, this line:
<%= f.label #type %> <label> Description</label>
depending on what view you are on shows ether:
Group Description
or
Tag Description
and because they are both technically the same, I am using the same index for both. I hope I am clear with my issue and thank anyone who understands my problem and solution.
The param name will depend on the object you pass.
If #type contains an instance of Group, then you will get the params under params[:group], and if it is an instance of Tag, the you will get them on params[:tag]
<%= form_for #type do |f| %>
<%= f.label :name, "#{#type.model_name} Description" %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
Note the label definition. The way you are defining it will create 2 labels and the second one will not be linked to any field.
fields_for is normally used when you are creating several objects within the same form, for instance a Project and several tasks associated to it.
Hope this helps.
update:
If #type is a string or symbol it should work too. The tradeoffs using this approach will be that if there are any validation errors when creating the object, those will not be displayed and the fields will not be prefilled with the input that the user gave before submitting the form, forcing the user to enter all the information again and guessing which was the validation error (you can initialize it from the received params, but that complicates the code readability)
The unique thing different in your view would be the label definition.
<%= f.label :name, "#{#type} Description" %>
I'm in the middle of trying to create a form where one of the questions is to choose a specific language. I'm trying to use the language list gem here: https://github.com/scsmith/language_list . However, the documentation doesn't really show me how I would combine the list with a select_tag.
<%= form_for users_path, :method => "get" do %>
<%= label_tag "Select Country" %> <br>
<%= country_select(:user, :country, [], :include_blank => true) %> <br>
<%= label_tag "Language spoken" %>
<%= select_tag "Language", options_from_collection_for_select(LanguageList::COMMON_LANGUAGES, "id", "name") %>
<%= label_tag "City" %> <br>
<%= text_field_tag(:city) %>
<% end %>
gives me the error
undefined method 'id' for afr (af) - Afrikaans:LanguageList::LanguageInfo
on the line
<%= select_tag "Language", options_from_collection_for_select(LanguageList::COMMON_LANGUAGES, "id", "name") %>
Can anyone help me?
Don't use "id". The docs say you should use iso_639_1 (or iso_639_3 if you want 3-letter codes)
<%= select_tag "Language", options_from_collection_for_select(LanguageList::COMMON_LANGUAGES, "iso_639_1", "name") %>
The LanguageList class seems to return a hash of LanguageInfo instances, having attributes like name, type and code -- `options_from_collection_for_select' expects its first parameter to be the collection (the hash in this case), the second a method that will return the value you want to identify the item, and the third is a display string.
So when someone selects a language, what are you going to store in the database? Probably one of the codes, right? So in this were true, you would make the second argument a method that an instance of the collection would respond to, which (reading the source code of the gem) is either iso_639_1 or iso_639_3. name should already work.
So if you replace id with one of those two iso_nnn_n values, then the form should display. To actually save the language code in the database, you'll need a column in your database for it, which you may already have as language.
Sometimes it's make a lot of sense to store gem's data dump in the database.
here is sample with postgresql and rails https://github.com/serghei-topor/import-language-list-into-db-rails-sample
here is csv file of gem's data dump https://github.com/serghei-topor/language-list-csv
And select_tag will look like:
<%= select_tag "Language", options_from_collection_for_select(Language.where(is_common:true).order(:name), "id", "name") %>