form_for in Ruby on Rails app - ruby-on-rails

I am trying to create a school model, which users can create, with the attributes of :school_name (string) , :description (string), and :created_by_user (integer).
The users should only be able to access and change the name and description parameters, and the created_by_user field should be automatically set to the id# of the user who created it.
this is my form for a new school:
<h1>Open a New School</h1>
<%= form_for(#school) do |f| %>
<%= render 'shared/error_messages', :object => f.object %>
<%= render 'fields', :f => f %>
<div class="actions">
<%= f.submit "Create School!" %>
</div>
and this is the "fields" partial
<div class="field">
<%= f.label :school_name %><br />
<%= f.text_field :school_name %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description, :size => "45x10" %>
</div>
What can I add in the "fields" partial, or anywhere else, so that when users create a new school their ID automatically gets set as the created_by_user value?
Thanks

You'll want to define this in your controller, rather than your view. Something like:
class SchoolsController < ApplicationController
def create
#school = School.new(params[:school])
#school.created_by_user = current_user
if #school.save
redirect_to #school, notice: "School Created"
else
render :new
end
end
end

Related

How can I redirect with submit button in rails?

I have this HTML:
<% provide(:contact, "active") %>
<% provide(:title, "Contacto | Recotiendame") %>
<div align="center">
<h1 id_"page_title">Contactanos!</h1>
<div class="skinny_wrapper wrapper_padding"
<%= form_for contact_path, url: #done do |f| %>
<%= f.label :Nombre %><br>
<%= f.text_field :Nombre, required: true %>
<br>
<%= f.label :Email %><br>
<%= f.email_field :Email, required: true %>
<br>
<%= f.label :Mensaje %><br>
<%= f.text_area :Mensaje, as: :text %>
<div class= "hidden">
<%= f.label :nickname %><br>
<%= f.text_field :nickname, hint: 'dejalo en blanco' %>
</div>
<br>
<%= f.submit 'Enviar Mensaje', class: "button" %>
</div>
<% end %>
</div>
with this controller:
class ContactController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
#contact.request = request
if #contact.deliver
flash.now[:notice] = 'Gracias por su mensaje. Lo contactaremos luego!'
else
flash.now[:error] = 'No se pudo enviar el mensaje.'
render :new
end
end
end
The problem is that the submit button does nothing. How can I make it work to redirect me to create? I have seen lots of answers to this question but none works for me.
EDIT 1
When I did #done, it was only to try things.
If I had to guess, I think you've got your form_for fields wrong. Normally you'd have something like: form_for #contact and it'd Just Work, but if you wanted to override the default url, you'd pass a different url eg
form_for #contact, url: contacts_path`
(note the plural is important).
I don't know what #done is meant to be... but it probably shouldn't be there... and putting the contact_path has two incorrect things about it:
1) you shouldn't have a url at that point, but an object (in this case the object is the contact)
2) contact_path is for showing a single contact that has already been saved, for creating a new contact, you need contacts_path (the idea is that you're posting a new contact to the set of contacts).

How do i make one form for two related models?

I want to write data for 2 different models that are related to each other like this:
class Post < ActiveRecord::Base
has_many :roads
accepts_nested_attributes_for :roads, :allow_destroy => true
end
class Road < ActiveRecord::Base
belongs_to :post
end
Of course de roads table has a "post_id column". My form_for in the post view looks like this
<%= form_for #post do |f| %>
<div class="form-group">
<%= f.label :Tu_Nombre %>
<%= f.text_field :creador, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :año %> (Cuando fue tu experiencia?)
<%= f.text_field :año, class: "form-control" %>
</div>
<div class="form-group">
<%= fields_for :roads do |r| %>
<%= r.label :principio %> (desde?)
<%= r.text_field :principio, class: "form-control" %>
<%= r.label :final %> (hasta?)
<%= r.text_field :final, class: "form-control" %>
<% end %>
</div>
<div class="form-group">
<%= f.label :historia %> (Cuentanos la historia de tu viaje!)
<%= f.text_area :historia, class: "form-control", size: "50x15" %>
</div>
<div>
<%= f.submit class: "btn btn-success" %>
</div>
<% end %>
Finally my posts_controller create method
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post, notice: 'Post was successfully created.'
else
render :new
end
end
with the private
def post_params
params.require(:post).permit(:historia, roads_attributes: [:pricipio, :final, :post_id])
end
The post is submitted and if i check the console all the atributes for post has been saved but the ones for road, has not. How can i use just one form two make records for these two models and that the post_id gets registered so i can relate the tables?
Thanks a lot!!
Update your posts_controller new method to include .build
def new
#post = Post.new
#post.roads.build
end
Please read the Nested Forms in Form Helpers chapter of Rails Guide. You could use fields_for to build the nested attributes form for your roads and permit nested attributes like the example. Below is an example from rails guide, you could try and figure it out yourself.
_form.html.erb
<%= form_for #person do |f| %>
Addresses:
<ul>
<%= f.fields_for :addresses do |addresses_form| %>
<li>
<%= addresses_form.label :kind %>
<%= addresses_form.text_field :kind %>
<%= addresses_form.label :street %>
<%= addresses_form.text_field :street %>
...
</li>
<% end %>
</ul>
<% end %>
permit nested attributes in people_controller.rb
def person_params
params.require(:person).permit(:name, addresses_attributes: [:id, :kind, :street])
end
Attach your fields_for to the parent form builder like so:
<%= f.fields_for :roads do |r| %>

Saving to an enum field in Rails 4.1.1

I am trying to make use of the enum feature that has been added to Rails. I had been waiting for this for quite some time.
Here is how I set it up:
Product model:
enum category: [:t_shirt, :hoodie, :jacket]
Product controller:
def create
#product = Product.new(product_params)
if #product.save
redirect_to #product, notice: 'Product was successfully created.' }
else
render :new
end
end
def product_params
params.require(:product).permit(:title, :description, :category, :price)
end
New form
<%= form_for(#product) do |f| %>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :price %><br>
<%= f.text_field :price %>
</div>
<div class="field">
<%= f.label :category %><br>
<%= f.select :category, Product.categories, include_blank: "Select a category" %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
This correctly populates the drop-down field in my form with the values of the different enum options which I have defined in the model.
However, when I submit the form having selected one of the categories from the drop-down, it gives me an error:
'0' is not a valid category
Even though my category field is an integer field and '0' is the correct integer associated with the category I selected in my form.
It also highlights the following line from the create method in my Product controller as the place where the error occured:
#product = Product.new(product_params)
I am completely confused as to why this is happening. Would really appreciate some help.
Thank you.
Instead:
<%= f.select :category, Product.categories, include_blank: "Select a category" %>
Try:
<%= f.select :category, Product.categories.keys, include_blank: "Select a category" %>
Explain:
In Product.categories hash {"t_shirt"=>0, "hoodie"=>1, "jacket"=>2} but in Product.categories.keys array what you need ["t_shirt", "hoodie", "jacket"] for select helper.

Rails 4 custom controller action error - "Couldn't find 'model' without an ID"

I'm trying to add a custom create action for my Book model, but i keep ending up with a "Couldn't find Book without an ID".
routes.rb:
Books::Application.routes.draw do
resources :books
resources :books do
collection do
post 'create_new_record', :action => :create_new_record
end
end
match 'create_new_record' => 'books#create_new_record', via: [:post]
The relevant controller action:
def create_new_record
#book = Book.new(book_params)
respond_to do |format|
if #book.save
format.html { redirect_to #book, notice: 'New book record created.' }
end
end
end
And my form (in new.html.erb). I'm looping through results that i get from goodreads.com.
<% #book_search.results.work.each do |stuff| %>
<%= form_for(#book, :url => create_new_record_books_path) do |f| %>
<div class="field">
<%= f.label :author %><br>
<%= f.text_field :author, :value => stuff.best_book.author.name %>
</div>
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title, :value => stuff.best_book.title %>
</div>
<div class="field">
<%= f.label :isbn %><br>
<%= f.text_field :isbn, :value => stuff.best_book.isbn %>
</div>
<div class="field">
<%= f.label :image %><br>
<%= f.text_field :image, :value => stuff.best_book.image_url %>
</div>
<div class="field">
<%= f.label :bookid %><br>
<%= f.text_field :bookid, :value => stuff.best_book.id %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<hr>
<% end %>
The error i get when submitting the form is:
ActiveRecord::RecordNotFound in BooksController#create_new_record
on the callback
def set_book
#book = Book.find(params[:id])
end
I'm pretty much stumped now, my understanding is that it doesn't even reach the action, but instead looks for a book id that doesn't exist?
Thank you!
If you use before_filter so you don't pass an id to create action. Call your before filter the following way:
before_filter :set_book, except: [:index, :new, :create]
If you use model callback, params is unavailable in the model so pass the id some other way, for example via attr_accessor.
use #book = Book.where(id: params[:id]).first

Ruby On Rails Form with integers titles instead of numbers in a drop-select-list

Hi
I'm pretty new with Ruby On Rails, and came across this problem.
I have 4 tables, and 1 that has the three others connected to it.
Sportcategories - name of each category
Sports - Name of each sport
Clubs - Name of each club
Results,
t.integer "sportcategory_id"
t.integer "sport_id"
t.integer "club_id"
I have managed to make a simple edit form with text_field for each field in results. But how can I get the names for the integers instead of the numbers?
<%= form_for(#result) do |f| %>
#if...
#..
#end
<div class="field">
<%= f.label :sportcategory_id%><br />
<%= f.text_field :sportcategory_id%>
</div>
<div class="field">
<%= f.label :sport_id %><br />
<%= f.text_field :sport_id %>
</div>
<div class="field">
<%= f.label :club_id %><br />
<%= f.text_field :club_id %>
</div>
<div class="field">
<%= f.label :result %><br />
<%= f.text_field :result %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I have made it so that SportCat, Sports and clubs has many results and that results belongs to all of them.
This is my controller file for results with edit & update
def edit
#result = Price.find(params[:id])
end
def update
#price = Price.find(params[:id])
respond_to do |format|
if #price.update_attributes(params[:price])
format.html { redirect_to(#price, :notice => 'Price was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #price.errors, :status => :unprocessable_entity }
end
end
end
And question two might be answered in question one, but I want to be able to choose from a drop-down list from all the available categories, sports and clubs with their actual name and then pass the right ID when I update it.
Check the Rails Form select helper
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-select
<%= form_for(#result) do |f| %>
<div class="field">
<%= f.label :sportcategory_id%><br />
<%= f.select :sportcategory_id, #sportcategories.map {|s| [s.name, s.id]} %>
</div>
<div class="field">
<%= f.label :sport_id %><br />
<%= f.select :sport_id, #sports.map {|s| [s.name, s.id]} %>
</div>
<div class="field">
<%= f.label :club_id %><br />
<%= f.select :club_id, #clubs.map {|c| [c.name, c.id]} %>
</div>
<div class="field">
<%= f.label :result %><br />
<%= f.text_field :result %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Get #sportcategories, #sports, #clubs in your controller actions.

Resources