Rails input from view - ruby-on-rails

In rails how do you get information from view to use in a controller. Like if i have a page with a text field and a button, how would i send the value from the field (without a model) into my controller to work with it in one of my functions. Im using rails 3

Sounds like you could use a simple form, for example:
in your views/products/index.html.erb:
<% form_tag omg_products_path do %>
<%= text_field_tag :my_input %>
<%= submit_tag "Send input" %>
<% end %>
in your controllers/products_controller.rb:
def omg
my_input = params['my_input']
#do whatever you want with my_input
end
You will also want to configure routes.rb, for example like this:
resources :products do
post :omg, :on => :collection
end

I think you will still want a model, but just use a Non Active Record Model see this Rails Cast: http://railscasts.com/episodes/121-non-active-record-model

Related

How to update an existing record?

I have a Books model and it has CRUD operations. In config/routes.rb, I have declared
map.resources :books
My new.html.erb looks like as:
<%= form_for :book, url: books_path do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.submit :Add %>
<% end %>
My create method in controller looks like as:
def create
book = Book.new(authorized_params)
book.save
end
So, when I submit my form from views, request would go to the 'create' method and an record for the book gets created in database. Fair enough. Now, I want to have an edit page for book. So, my edit method in controller look like as:
def edit
#book = Book.find_by(params[:id])
render :new
end
When I go to my edit view, it automatically show the value of title in the text box, which is what I expected.. But when I try to submit the form again(ofcourse after changing the title value) it again creates a new record instead of updating it..
Something basic which I missed out in my reading? I googled about it though but did not find satisfactory answer.
The issue is that you are using the 'new' view where form has the post method. If you will check the generated routes, post will be for create method, that is adding a new record. You will have to create a new view for edit where the form target URL will be edit_book_path(#book) and method will be patch. Patch method will route to 'update' function in your controller where you will call #book.update. I am not writing the exact code, but these directions should help you achieve what you want

Rails: Form helper for enum attribute

I set category's viewable attribute as an enum
class Category < ActiveRecord::Base
enum viewable: [:only_self, :friends, :anyone]
end
How should I make them accesible in _form when users edit this attribute? Something like?
<%= form_for(#category) do |f| %>
<%= f.select(:viewable) %>
<% end %>
UPDATE------
<%= f.select(:viewable, options_for_select([["description1", "only_self"], ["description2", "friends"], ["description3", "anyone"]])) %>
The description for each is quite repetative, because I need to put them whenever I need to display, not just in the forms. Where should I put them?
In form_for, the f.select does not display the current value of the this field. It always is the first description1.
When using the plural form, rails provides the full key/value array, so you can call Category.viewables for the array, and with the help of options_for_select you'll get a nice functioning dropdown list
<%= form_for(#category) do |f| %>
<%= f.select(:viewable, options_for_select(Category.viewables)) %>
<% end %>
Updated answers
The description for each is quite repetative, because I need to put
them whenever I need to display, not just in the forms. Where should I
put them?
You can use the I18n library, assuming your locale is chinese (zh i think) then you could create /config/locales/zh.yml and add something like this
categories:
viewable:
only_self: 'some chinese text'
friend: 'more chinese text'
anyone: 'well you know'
Then better create some helper that returns the localized options
def options_for_viewables
{
t('categories.viewable.only_self') => 0,
t('categories.viewable.friends') => 1,
t('categories.viewable.anyone') => 2
}
end
The view will become like this
<%= f.select(:viewable, options_for_viewables) %>

Trying to fire an action in my controller when a selection in a drop down menu is made but getting a no route matches error

I'm building a web interface to accompany a mobile app I'm building. I have a drop down select menu that lists a bunch locations.
On selection of a location I want to make a call to a method in my controller and grab some destinations within the location that was selected (each location has several destinations).
I then would like to render my show template with these results allowing the user to select a destination and make a booking.
This is what I have so far:
My view with a list of resorts:
<%= form_tag :url => { :action => :show } do %>
<%= select_tag :resort , options_for_select(#resorts), :prompt => 'Select Resort', :onchange => 'submit()' %>
<% end %>
Controller:
class HomeController < ApplicationController
def index
#resorts = ["A","B", "C", "D", "E"]
end
def new
end
def edit
end
def create
end
def show
#activities = Parse::Query.new("Activity").tap do |a|
a.eq("resort", params[:resort])
end.get
end
end
Just slightly confused. Using form_for makes more sense to me with CRUD in mind and also because the form is object based.
I'd like to just take the selected resorted and pass it into a method in my controller that goes into a database and grabs a bunch of destinations. I then want to list these destinations on my show page where a user can click and be taken to another page where they can make a booking at that destination.
My above code doesn't work. I have resources :home in my routes file.
However when I try to load my page with the form I get:
No route matches {:action=>"show", :controller=>"home"} missing required keys: [:id]
How do I pull this off?
I went on my lynda account and pulled up a rails essential tutorial which I'll have to use to refresh my memory some time tomorrow but the tutor doesn't cover use of select_tag.
Would appreciate some help here
Thanks for your time
So a few thoughts. Not sure why you are using form_tag and also not sure why you aren't using Rails idiomatic conventions.
Declare a resource in your routes for #resorts, like so:
resources :resorts
Then just use Rails form_for helper like:
<%= form_for #resorts, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
<%= f.select :resort, (insert your other options) %>
<%= f.submit "Create" %>
<% end %>
I have not tested the above code, so play around with it, but that should work.
However, let me save you some headache. Checkout SimpleForm.
For your models, you would want to setup an association between your locations and destinations.
class Location < ActiveRecord::Base
belongs_to :resort # or whatever the relation is
has_many :destinations
end
class Destination < ActiveRecord::Base
belongs_to :location # This assumes there is just a one-to-many relationship between Location and Destination
end
Make sure you have a LocationsController with all the actions.
In this case, your SimpleForm form would look something like this:
<%= simple_form_for #locations do |f| %>
<%= f.input :name %>
<%= f.association :password %>
<%= f.button :submit %>
<% end %>
That approach will make your life much easier. Take a look at the collections methods in Simple Form. Rails can make your life difficult with the built in form helpers.
Hope that helps!
In your routes, add
get '/choose_resort' => 'home#show' #you can name the get whatever
Then in your form...
<%= form_tag choose_resort_path do %>
That being said... you should have your query at a separate endpoint, and redirect to the show page. That should get you moving, methinks.
The show action needs an id of the object you are showing. Change your controller:
class HomeController < ApplicationController
def index
#resorts = [["A",1], ["B",2], ["C",3], ["D",4], ["E",5] ]
end
And your view
<%= select_tag :id , options_for_select(#resorts), :prompt => 'Select Resort', :onchange => 'submit()' %>
That gives your show action the proper resort id. You'll have to adjust that action to find the right activities relevant to the resort.

Passing a parameter between views in Rails

I am trying to accomplish something like this:
I am creating a simple blog. I have set up categories for my blog.
I want that when my user goes to posts/index, he sees a list of all categories.
Example:
Text
Image
Upon clicking on a category, my user gets redirected to the posts/new page, where the category_id field will by transmitted through a hidden_field.
So my code right now is:
in posts/index
<% #categories.each do |c| %>
<%= link_to c.name, new_post_path(:category => c.id) %><br />
<% end %>
and in my posts/_form i'm trying to do something like this
<%= f.hidden_field :category_id, :value => params[:category_id] %>
which is not working though, because the html output is
No value is being passed.
What is the correct way to proceed here?
Thx!
At first glance it looks like a simple mistake mixing up the param names category and category_id.
Try this:
<% #categories.each do |c| %>
<%= link_to c.name, new_post_path(:category_id => c.id) %><br />
<% end %>
Also, from what i can understand in your code, it seems a post belongs to a category. In such case, you could nest routes from one in another, and paths for creating nested object would become accessible, such as new_category_post(#category).
The routing would look like that:
resources :categories do
resources :posts
end
You can read about this matter here: http://guides.rubyonrails.org/routing.html

Rails Multiple Entries in a form

I'll try and explain this as much and as easily as possible.
I have a Rails form, and 3 models.
Models: DemoModule, SalesDemo, and SalesDemoModule
What I want to do in my view/form is create a new SalesDemo, but a SalesDemo has many SalesDemoModules.
In the controller I have:
#sales_demo = SalesDemo.new
#demo_modules = DemoModule.find(:all, :conditions => ['active = true'])
How can I, in my view, have a text field row for each DemoModule, which I can pass back to the controller action, to save into SalesDemoModule?
You can specify that the SalesDemo accepts_nested_attributes_for SalesDemoModule, which then allows you to created a nested form (i.e. within a form_for a SalesDemo, you can have fields_for SalesDemoModule). Here's a simple example.
Simply put:
<%= form_for #sales_demo do |sales_demo_form| %>
<%= sales_demo_form.text_field "some_sales_demo_property" %>
<%= sales_demo_form.fields_for #demo_modules do |modules| %>
<%= modules.text_field "some_module_text_field" %>
<% end %>
<% end %>
In the SalesDemo, you will need to have
accepts_nested_attributes_for :demo_modules
You can get some more information here.

Resources