Rails Model Association with form - ruby-on-rails

I am trying to achieve this:
It has a model called Customer that has details of the customers name
(first, middle and last) and telephone numbers (mobile and landline).
It has a model called Address that is linked to Customer. This model
will have details for a customers address (a number of address lines,
a country and a post/zip code).
A customers controller that supports two pages. The first will list
all customers in the database along with their associated address.
The second will display a form for the entry of a new customer along
with their address and allow for the creation of a new customer and
address record. It should be possible to move from either page to the
other without having to enter an URL in the browser navigation bar.
A number of points of note about this are as follows...
This is my code:
Migration:
class CreateAddresses < ActiveRecord::Migration
def change
create_table :addresses do |t|
t.string :address_line1
t.string :address_line2
t.string :address_line3
t.string :city
t.string :county_province
t.string :zip_or_postcode
t.string :country
t.string :customer_id
t.timestamps null: false
end
create_table :customers do |t|
t.string :first_name
t.string :middle_name
t.string :last_name
t.integer :mobile_number
t.integer :landline_number
t.timestamps null: false
end
end
end
Model:
class Address < ActiveRecord::Base
end
class Customer < ActiveRecord::Base
has_one :address
end
Form:
<%= form_for([#address,#customer]) do |f| %>
<% if #customer.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#customer.errors.count, "error") %> prohibited this customer from being saved:</h2>
<ul>
<% #customer.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :first_name %><br>
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :middle_name %><br>
<%= f.text_field :middle_name %>
</div>
<div class="field">
<%= f.label :last_name %><br>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :mobile_number %><br>
<%= f.number_field :mobile_number %>
</div>
<div class="field">
<%= f.label :landline_number %><br>
<%= f.number_field :landline_number %>
</div>
<div class="field">
<%= f.label :address_line1 %><br>
<%= f.text_field :address_line1 %>
</div>
<div class="field">
<%= f.label :address_line2 %><br>
<%= f.text_field :address_line2 %>
</div>
<div class="field">
<%= f.label :address_line3 %><br>
<%= f.text_field :address_line3 %>
</div>
<div class="field">
<%= f.label :city %><br>
<%= f.text_field :city %>
</div>
<div class="field">
<%= f.label :county_province %><br>
<%= f.text_field :county_province %>
</div>
<div class="field">
<%= f.label :zip_or_postcode %><br>
<%= f.text_field :zip_or_postcode %>
</div>
<div class="field">
<%= f.label :country %><br>
<%= f.text_field :country %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Routes:
resources :addresses do
resources :customers
end
resources :customers do
resources :addresses
end
I haven't changed anything in my both controllers.
I am getting this error: undefined method `address_line1' for #
I don't understand where i am wrong. Any help? :( please
Schema:
ActiveRecord::Schema.define(version: 20150722160725) do
create_table "addresses", force: :cascade do |t|
t.string "customer_id"
t.string "address_line1"
t.string "address_line2"
t.string "address_line3"
t.string "city"
t.string "county_province"
t.string "zip_or_postcode"
t.string "country"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "addresses", ["customer_id"], name: "index_addresses_on_customer_id"
create_table "customers", force: :cascade do |t|
t.string "first_name"
t.string "middle_name"
t.string "last_name"
t.integer "mobile_number"
t.integer "landline_number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end

Related

Ruby on Rails: Saving form check boxes to Boolean in Postgres

Rails noob here, how do I get a Rails form to save a boolean checkbox to postgres? I've tried dozens of things I've found online and none of it is working. No matter what I do, the entry in the Postgres DB is "Null". Here is my
Model(schema):
ActiveRecord::Schema.define(version: 20171227200151) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "notes", force: :cascade do |t|
t.string "note_title"
t.string "note_text"
t.boolean "note_scratch", default: false, null: false
t.boolean "note_info"
t.boolean "note_reminder"
t.boolean "note_task"
t.string "note_tags"
t.date "note_remind_date"
t.time "note_remind_time"
t.integer "note_archived"
t.date "note_archived_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
view:
<%= form_with scope: :note, url: notes_path, local: true do |f| %>
<p>
<%= f.label :note_title %><br>
<%= f.text_field :note_title %>
</p>
<p>
<%= f.label :note_text %><br>
<%= f.text_area :note_text %>
</p>
<p>
<%= f.label :notes_scratch, "Scratch" %>
<%= f.check_box :notes_scratch %>
<%= f.label :notes_info, "Info" %>
<%= f.check_box :notes_info %>
<%= f.label :notes_reminder, "Reminder" %>
<%= f.check_box :notes_reminder %>
<%= f.label :notes_task, "Task" %>
<%= f.check_box :notes_task %>
</p>
<p>
<%= f.label :note_tags %><br>
<%= f.text_field :note_tags %>
</p>
<p>
<%= f.label :note_remind_date %><br>
<%= f.date_field :note_remind_date %>
</p>
<p>
<%= f.label :note_remind_time %><br>
<%= f.time_field :note_remind_time %>
</p>
<%= f.submit %>
<% end %>
Controller:
class NotesController < ApplicationController
def new
end
def create
# for testing
# render plain: params[:note].inspect
#note = Note.new(note_params)
#note.save
redirect_to #note
end
private
def note_params
params.require(:note).permit(:note_title, :note_text, :note_scratch, :note_info, :note_reminder, :note_task, :note_tags, :note_remind_date, :note_remind_time, :note_archived, :note_archived_date)
end
end
If I just render the form results, it will show checked boxes as 1s, but it always comes up Null in the database, even if I set the datatype to Integer (hoping it would store the 1). All of the other fields record just fine. It's only the checkboxes that don't work.
I appreciate any assistance you can lend!
-Brick
Review your note_params (and schema.rb):
def note_params
params.require(:note).permit(:note_title, :note_text, :note_scratch, :note_info, :note_reminder, :note_task, :note_tags, :note_remind_date, :note_remind_time, :note_archived, :note_archived_date)
end
In your view: notes_* needs to be singular as your schema is note_*.

Choose right method in Controller according to the forms - Rails 5

I have two models: Entreprise & Prospect
create_table "entreprises", force: :cascade do |t|
t.string "name"
t.text "adresse"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "siret"
t.string "numtva"
t.string "tel"
t.integer "prospect_id"
end
create_table "prospects", force: :cascade do |t|
t.string "full_name"
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "entreprise_id"
end
Prospects belongs_to entreprises, and Entreprise has_many Prospects.
-
My issue :
I have two buttons : Create a new entreprise or reate a new prospect.
I have two way to create a new prospect :
Under my entreprise because an entreprise has_many prospects
Directly from navbar with "create prospect" button
So I have two forms :
If we click on "create prospect" (create method in my controller):
<%= form_for :prospects, url: prospects_path do |f| %>
<p>
<%= f.label :entreprises %><br><br>
<%= f.collection_select :entreprise_id, Entreprise.order(:name),:id,:name, include_blank: true %>
</p><br>
<p>
<%= f.label :full_name %> <br>
<%= f.text_field :full_name %><br>
</p><br>
<p>
<%= f.label :email %> <br>
<%= f.text_field :email %><br>
</p><br>
<p>
<%= f.submit %>
</p>
<% end %>
If we create prospect under entreprise ("directcreate" method in my controller) :
<%= form_for([#entreprise, #entreprise.prospects.build]) do |f| %>
<p>
<%= f.label :full_name %> <br>
<%= f.text_field :full_name %><br>
</p><br>
<p>
<%= f.label :email %> <br>
<%= f.text_field :email %><br>
</p><br>
<p>
<%= f.submit %>
</p>
<% end %>
My Controller for Prospects :
class ProspectsController < ApplicationController
def index
#prospects = Prospect.all.limit(15).order('created_at DESC')
end
def new
#prospect = Prospect.new
end
def directcreate
#prospect = Prospect.new(entreprise_params)
if #prospect.save
redirect_to #prospect
else
render 'new'
end
end
def create
#entreprise = Entreprise.find(params[:entreprise_id])
#prospect = #entreprise.prospects.create(params[:prospect].permit(:full_name, :email))
redirect_to entreprise_path(#entreprise)
end
def destroy
#entreprise = Entreprise.find(params[:entreprise_id])
#prospect = #entreprise.prospects.find(params[:id])
#prospect.destroy
redirect_to entreprise_path(#entreprise)
end
end
My problème is that the "create" method in my controller is the only one who works.. and not "directcreate" method.
--
QUESTION : How can I do to choose the controller I want according to the form ?
My question is probably not well ask.
FYI I try this in my new.html.erb :
<%= render 'formdirect', :controller => "directcreate" %>
but it doesn't work.
You can try something like this. You just have to explicitly choose your controller action.
<%= form_for([#entreprise, #entreprise.prospects.build], :url => { :action => : directcreate }) do |f| %>
<p>
<%= f.label :full_name %> <br>
<%= f.text_field :full_name %><br>
</p><br>
<p>
<%= f.label :email %> <br>
<%= f.text_field :email %><br>
</p><br>
<p>
<%= f.submit %>
</p>
<% end %>

Rails many to many model with select in the view

The logic in the exercise is create a Bill where a Bill have a list of Products with an amount of them.
I have the next 3 models:
Bill
Product
BillItem (This is the intermediate model between Bill and Product for the many to many relationship)
Schema for more clarity:
create_table "bill_items", force: :cascade do |t|
t.integer "amount"
t.integer "product_id"
t.integer "bill_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["bill_id"], name: "index_bill_items_on_bill_id"
t.index ["product_id"], name: "index_bill_items_on_product_id"
end
create_table "bills", force: :cascade do |t|
t.string "user_name"
t.string "dni"
t.date "expiration"
t.float "sub_total"
t.float "grand_total"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "description"
t.float "price"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
First i have a list of created products in my database.
For my BillController i have a _form.html.erb where i want be capable to create dynamic selects for choose a product and set a amount.
My view is the next:
<%= form_for bill do |f| %>
<div>
<%= f.label :user_name %>
<%= f.text_field :user_name %>
</div>
<div>
<%= f.label :dni %>
<%= f.text_field :dni %>
</div>
<div>
<%= f.label :product %>
<%= f.collection_select :product_ids, Product.all, :id, :name %>
</div>
# Here i should add more selects if the user want to add more products.
<div><%= f.submit %></div>
<% end %>
My problem or my question is: how to "groupe" the ids of the products and the amount of them. And the another question is, i can create the other selects dynamically with JS?
You need to be adding multiple BillItem to your form to account for the amount and the product. This is done through accepts_nested_attributes_for on the model. For example:
class Bill < ActiveRecord::Base
has_many :bill_items
accepts_nested_attributes_for :bill_items
end
Initialize a BillItem on the Bill in your controller:
class BillsController < ActionController::Base
def new
#bill = Bill.new
#bill.bill_items.build
end
end
Then in your form, use the fields_for helper to create sub-forms:
<%= form_for #bill do |f| %>
<div>
<%= f.label :user_name %>
<%= f.text_field :user_name %>
</div>
<div>
<%= f.label :dni %>
<%= f.text_field :dni %>
</div>
<%= f.fields_for :bill_items do |f| %>
<div>
<%= f.label :product %>
<%= f.collection_select :product_id, Product.all, :id, :name %>
</div>
<div>
<%= f.label :amount %>
<%= f.number_field :amount %>
</div>
<% end %>
<%= f.submit %></div>
<% end %>
And yes, you can use javascript to create new nested forms.

Image upload using carrierwave in show page

Using Rails 4 and Ruby 2.2,
I have book as model which should have image upload functionality in the show page of book. So User can create the book first and from show page upload the multiple images for book. I have used carrierwave as gem and have separate model created for Image.
image.rb
class Image < ActiveRecord::Base
belongs_to :book
mount_uploader :avatar, AvatarUploader
end
book.rb
class Book < ActiveRecord::Base
belongs_to :subject, dependent: :destroy
belongs_to :user, dependent: :destroy
has_many :images, dependent: :destroy
end
books/show.html.erb
<%= form_for(Image.new, :html => { :multipart => true }) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
<%= hidden_field_tag "image[book_id]", #book.id %>
</div>
<%= f.fields_for :images do |p| %>
<div class="field">
<%= p.label :avatar %><br>
<%= p.file_field :avatar, :multiple => true, name: "images[avatar]" %>
</div>
<%end%>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
schema.rb
create_table "images", force: :cascade do |t|
t.datetime "avatar_updated_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "book_id", limit: 4
t.string "avatar", limit: 255
t.string "name", limit: 255
end
create_table "books", force: :cascade do |t|
t.string "title", limit: 255
t.integer "page_number", limit: 4
t.text "description", limit: 65535
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id", limit: 4
t.integer "subject_id", limit: 4
t.boolean "active", default: false
end
Now I am kind of unable to proceed with this, can someone guide me on this because I am having form in books/show page and I need to show the image on the same page after successful updation of images.(Multiple images can be uploaded)
Thanks in advance
let me know if I need to provide any more information.
You can use the association itself and list all the images which have been uploaded.
<%= form_for(Image.new, :html => { :multipart => true }) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
<%= hidden_field_tag "image[book_id]", #book.id %>
</div>
<%= f.fields_for :images do |p| %>
<div class="field">
<%= p.label :avatar %><br>
<%= p.file_field :avatar, :multiple => true, name: "images[avatar]" %>
</div>
<% end %>
<!-- Listing all the images for a book -->
<% if #book.images.any? %>
<% #book.images.each do |img| %>
<%= image_tag(img.avatar.url) %>
<% end %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

How to add text field in views to add content to other table inside a form

Im new to ror so sorry if that's a really basic question.
So, in my app i have quizzes and each quiz, beside questions and answers, should have 5 links.
class Quiz < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :questions
has_many :links
end
class Link < ActiveRecord::Base
belongs_to :quizzes
end
Schema looks like this:
create_table "links", force: true do |t|
t.string "name"
t.string "www"
t.integer "quiz_id"
end
create_table "questions", force: true do |t|
t.string "content"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "quiz_id"
end
create_table "quizzes", force: true do |t|
t.string "content"
t.datetime "created_at"
t.datetime "updated_at"
end
Now, in views I want to add links as i Add/Edit my quiz.
View for form looks like this:
<%= form_for(#quiz) do |f| %>
<% if #quiz.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#quiz.errors.count, "error") %> prohibited this quiz from being saved:</h2>
<ul>
<% #quiz.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br>
<%= f.text_field :content %>
<%= **THIS IS PLACE FOR TEXT FIELD FOR LINK_NAME AND LINK_WWW** %>
</div>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
How do I create a form to add the links?
You can use fields_for:
<%= f.label :content %><br>
<%= f.text_field :content %>
<%= f.fields_for #quiz.links.new do |ff| %>
<%= ff.label :name %>
<%= ff.text_field :name %>
<% end %>
And allow the Quiz to update the Link records associated:
class Quiz < ActiveRecord::Base
accepts_nested_attributes_for :links

Resources