Buttons to Update Attributes - ruby-on-rails-3

I have 3 models: Restaurant/User/Reservation.
Reservation belongs_to both other models (the other two are has_many, through:).
I need a user to be able to make a reservation # a restaurant. I wanted to make a button to do it:
<h1>Restaurants#index</h1>
<% #all.each do |x| %>
<%= link_to x.name %><br>
<%= x.image %><br>
<%= x.current_capacity %>/<%= x.capacity %>
<p><%= submit_tag "Reserve?" %></p>
<% end %>
How can I design this functionality? I was originally thinking to have a column under Restaurants for "capacity" and "current_capacity" and worry about using time later. How can I get this button to set an instance of Restaurant to update its current_capacity?

Related

Rails - How to get total of params

I have a Restaurant model.
Meeting model has_many :vouchers (integer)
Let's say I have 10 vouchers left, when I spent all vouchers until 0, it can be topped up to 10 more vouchers by admin (manually using restaurant form).
In Restaurant form:
<% if current_user.admin? %>
<%= form_for #restaurant %>
<%= f.number_field :voucher %>
<%= f.submit, value: 'Top Up Voucher' %>
<% end %>
<% end %>
In user show:
You have <%= #user.voucher %> vouchers left
My question is how to get total of voucher?
Ex: I have topped up voucher 3 times.
(3x10 vouchers) = **total 30 vouchers (this is what I want to get)**
I tried
<%= #user.voucher.size %>
and
<%= #user.voucher.count %>
but they both didn't work.
Thanks in advance for the help

how to sort a collection with simple form

I'm pulling a list of categories from a model.
In the admin section I want to use it to assign categories to products.
It's working fine but the list shows in the order the categories have been added.
I'd like to sort them alphabetically but I can't suss it out.
I'm sure it's pretty simple (hopefully)
here's my code:
<%= simple_form_for(#game) do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<%= f.input :copy %>
<%= f.input :image %>
<%= f.input :thumbnail %>
<%= f.input :heroimage %>
<%= f.association :category, collection: #categories %>
<%= f.button :submit %>
<% end %>
I tried to add a .sort_by(desc) or just .sort on the collection method but it doesn't change the list.
Cheers
Here is how you should update your code:
<%= f.association :category, collection: Category.order('name ASC') %>
This assumes you want to sort by the category name, in ascending order.
I imagine #categories is assigned as an arel in your controller, can you add an .order("description") to that; e.g.
#categories = Category.order('description')

Update model with response from an API after submitting form that uses nested attributes

Forgive me if this has been answered. I spent a few hours searching for the answer to this both here and on Google.
I'm just getting started with Ruby on Rails. I'm trying to update a model with data from an API response after saving the data originally submitted via the form to two different models.
So basically I have a User model and a Character model. The sign up form collects data on the user and their character. In order to make an API request I have to at least get a few details about the character to pass in as part of the requested attributes (i.e. name, realm).
So I'm using a form_for with nested attributes:
<%= form_for(#user) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :username %>
<%= f.text_field :username %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation, "Password Confirmation" %>
<%= f.password_field :password_confirmation %>
<%= f.fields_for :characters do |builder| %>
<%= builder.label :realm %>
<%= builder.text_field :realm %>
<%= builder.label :name %>
<%= builder.text_field :name %>
<% end %>
<%= f.submit "Sign Up" %>
<% end %>
This successfully submits all of the user info submitted to the User model and the realm and name submitted to the Character model. No problems there. However, I have several more fields that I want t fill in for the Character records just created from the API that provides all of the character info. What is the most efficient way to do this so that after the form submits, it updates the record (or adds data prior to save the record) with the data coming back from the API.
I don't need help on the specific fields and data returned. I have that all working, I'm just looking for a way to make the API request and complete the record with all data immediately after the form submits.
Suggest to use callback (:after_create) .
Depending upon the API processing you can choose between them .
:after_save
:before_save
:before_create
With any callback just get the data from your API and fill other character info's.
Hope that helps . Good luck .

Rails 3 ActiveRecord::UnknownAttributeError "unknown attribute: _destroy" for nested records

Let's say I have a schema in which an apple crate contains zero or more apples. While editing the apple crate in a form, I want to list the apples and provide a checkbox next to each apple, for deleting it when the form is submitted.
There is nothing going wrong that I can see. In my model I say
class AppleCrate < ActiveRecord::Base
has_many :apples
accepts_nested_attributes_for :apples, :allow_destroy => true
...
end
I have the form working, so far as I can tell. The checkboxes appear in the form html and when the form is processed by the controller each apple in the list has an attribute called "_destroy" which is set to either "1" or "0" depending on whether or not I checked the box before submitting.
According to the Rails API, when I set _destroy to 1 and save, the apple should be deleted. But when I submit the form I get
ActiveRecord::UnknownAttributeError in AppleCrateController#update
unknown attribute: _destroy
...
"apple_crate"=>{"id"=>"10101", "apples"=>{"1"=>{"id"=>"1",
"variety"=>"granny smith",
"apple_crate_id"=>"10101",
"_destroy"=>"1"},
"2"=>{"id"=>"2",
"variety"=>"fuji",
"apple_crate_id"=>"10101",
"_destroy"=>"1"},
"3"=>{"id"=>"3",
"variety"=>"macintosh",
"apple_crate_id"=>"10101",
"_destroy"=>"0"},
...
and so on.
I must be missing something obvious but after several days of futzing around I can't figure it out. I can successfully do everything else -- update, edit, index, etc -- so long as I leave out the :_destroy attribute. Any ideas?
(For what it's worth, I'm running rails 3.2.2 on Windows.)
Updated:
This is what I'm looking at in the documentation. (See the subsection "One-to-many".)
Updated:
As requested in comments, here is the view:
<%= form_for #apple_crate do |f| %>
<% #apples = #apple_crate.apples %>
<% #apples.each do |apple| %>
<%= fields_for "apples[]", apple do |apple_fields| %>
<%= apple_fields.text_field :variety %>
<%= apple_fields.hidden_field :apple_crate_id %>
<%= apple_fields.hidden_field :id %>
<%= apple_fields.check_box :_destroy %>
<% end %>
<% end %>
<%= f.submit "Save" %>
<% end %>
You should generate nested forms and forms with rails helpers, don't do it by your hands. So I think that's where your error at.
Try:
<%= form_for #apple_crate do |f| %>
<%= f.fields_for :apples do |apple_fields| %>
<%= apple_fields.text_field :variety %>
<%= apple_fields.hidden_field :apple_crate_id %>
<%= apple_fields.hidden_field :id %>
<%= apple_fields.check_box :_destroy %>
<% end %>
<% end %>
something like this, did not check if it's correct, but idea should be clear enough

Rails - Using form_for and fields_for, how do you access the sub-object while in the fields_for block?

In my first rails app I'm trying to use form_for and fields_for to create a nested object form. So far so good, but I can't figure out how to access the sub-object while in the fields_for block. I've pre-populated a field in the sub-object with data that I want to show in the user instructions.
Models
Garage:
has_many :cars, :dependent => :destroy
accepts_nested_attributes_for :cars
Car:
belongs_to :garage
Garage Controller
def new
#garage = Garage.new
for i in 1..5
#garage.cars.build :stall_number => i
end
end
_form.html.erb
<%= form_for #garage do |f| %>
<%= f.label :title, "Garage Name" %><br />
<%= f.text_field :title %>
<% f.fields_for :cars do |builder| %>
<p>Enter license for car parked in stall: <%= car.stall_number %></p>
<%= f.label :license, "License #:" %><br />
<%= f.text_field :license %>
<%= end %>
<%= end %>
As you can see, inside the builder block for :cars, I want to show, in my user instructions, the field: car.stall_number (populated in my controller with an integer):
<p>Enter license for car parked in stall: <%= car.stall_number%></p>
I've tried a many different ideas: #car.stall_number, object.car.stall_number, etc. No joy. Multiple searches and a look at the fields_for source code haven't helped my understanding. I would appreciate any guidance.
Update: For clarification, per Dan's suggestion I have tried builder.stall_number but it results in a
NoMethodError: undefined method 'stall_number' for #<ActionView::Helpers::FormBuilder:0x00000102a1baf0>
I just dealt with this today myself.
You can access the object of the fields_for through:
builder.object
where builder is your fields_for form builder object. In your particular case, you can say:
<p>Enter license for car parked in stall: <%= builder.object.stall_number%></p>
That should do it for you!
The way you are trying is does not work because you want to access car without filling that variable for data.
I guess you want to have multiple blocks of stalls, where you can enter license plates. For each stall you will need your own fields_for.
I would suggest something like that:
<%= form_for #garage do |f| %>
<%= f.label :title, "Garage Name" %><br />
<%= f.text_field :title %>
<% for i in 1..5 %>
<% f.fields_for #garage.cars[i] do |builder| %>
<p>Enter license for car parked in stall: <%= builder.stall_number%></p>
<%= builder.label :license, "License #:" %><br />
<%= builder.text_field :license %>
<% end %>
<% end %>
<% end %>
Within the fields_for you need to use the form object you define there, in this case builder. Since the data there are not mapped to the outer form (f), but to the cars object (builder).