Controller not processing params for table - ruby-on-rails

I want to save a record to a Bookings table that has foreign keys from Schedules and Users table.
Here is the schema:
create_table "bookings", force: :cascade do |t|
t.integer "seats"
t.integer "base_price"
t.integer "total_price"
t.string "status"
t.integer "schedules_id", null: false
t.integer "users_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["schedules_id"], name: "index_bookings_on_schedules_id"
t.index ["users_id"], name: "index_bookings_on_users_id"
end
create_table "schedules", force: :cascade do |t|
t.string "departure", null: false
t.string "destination", null: false
t.integer "seats_available", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.integer "price"
t.datetime "date_time"
end
create_table "users", force: :cascade do |t|
t.string "email", null: false
t.string "password_digest", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "firstname", null: false
t.string "lastname", null: false
end
Schedule and User has_many :bookings and Booking belongs_to :schedules and :users.
My view in bookings/new.html.erb
<%= form_for(#book, url: booking_path, local: true) do |f| %>
<% #books.each do |data| %>
<%= data.departure %>
<%= data.destination %>
<%= data.formatted_date_time %>
<%= data.seats_available %>
<%= data.price %>
<%= f.hidden_field :base_price, value: data.price %>
<%= f.hidden_field :seats %>
<%= f.hidden_field :total_price %>
<%= f.submit "Book" %>
<% end %>
<% end %>
I'm not sure this is the best way to do it but this is my attempt. Assume the hidden fields has a way to get the data, because I cut out the code that does it since I can see the params being passed in the Command Prompt.
My routes:
get 'booking', to: 'bookings#new'
post 'booking', to: 'bookings#create'
My BookingsController:
def new
#books = Schedule.where(id: params[:book_id])
#book = Booking.new
end
def create
#book = Booking.new(booking_params)
if #book.save
flash[:success] = 'success'
redirect_to root_path
end
end
private
def booking_params
params.require(:booking).permit(:base_price, :seats, :total_price)
end
In the command prompt it does display the parameters { "booking"=>{"base_price"=>"80", "seats"=>"2", "total_price"=>"160"}, "commit"=>"Book"}. The problem is that after that it now loads bookings/create.html.erb without saving the params. It somehow doesn't do the if #book.save part. Also I don't know how I can put the foreign keys or the :status variable or do I even need to. I appreciate the help!

Related

custom query in active record with multiple joins

I am very new to rails and active record so I'm probably doing something wrong, but... using the schema below, I want to create a list of courses in the outer do loop, then list each student enrolled in the course with the inner do loop. I m not sure if this approach will work, but this error keeps popping up:
ActionView::Template::Error (undefined method `enrollments' for #):
it seems that the association is made. what am i doing wrong?
Professor show page:
<div class="col-md-8">
<h2 class="card-title"><%= #professor.name %></h2>
<% #courses_taught.each do |course| %>
<div class="card mb-4 card-header">
<img class="card-img-top" src="http://placehold.it/750x300" alt="Card image cap">
<h3 class="card-text"><%= course.title %></h3>
</div>
<div class="card-body">
<% course.sections.enrollments.students.each do |student| %>
<p><% student.name %></p>
<% end %>
</div>
<% end %>
</div>
models:
enrollment
class Enrollment < ApplicationRecord
belongs_to :section
belongs_to :student
end
Student:
class Student < ApplicationRecord
has_many :enrollments
end
Professor:
class Section < ApplicationRecord
has_many :enrollments
belongs_to :professor
belongs_to :course
validates_uniqueness_of :professor_id, scope: :course_id
scope :by_professor_id, ->(prof_id) { where('professor_id = ?', prof_id) }
end
Course:
class Course < ApplicationRecord
enum status: { planning: 0, offered: 1 }
scope :offered, -> { where(status: 1) }
scope :planning, -> { where(status: 0) }
belongs_to :department
has_many :sections
has_many :professors, through: :sections
validates :title, :number, :status, :description, presence: true
validates :description, length: { in: 10..500 }
validates :title, :number, uniqueness: { case_sensitive: false }
def self.search(term)
if term
where('title LIKE ?', "%#{term}%").order('title DESC')
else
order('title ASC')
end
end
def self.taught_by(professor_id)
Course
.joins(:sections)
.joins(:professors)
.where(sections: { professor_id: professor_id })
.select('distinct courses.*')
end
end
Schema:
ActiveRecord::Schema.define(version: 20171013201907) do
create_table "courses", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", default: 0
t.integer "department_id"
t.index ["department_id"], name: "index_courses_on_department_id"
end
create_table "departments", force: :cascade do |t|
t.string "name"
t.text "description"
t.text "main_image"
t.text "thumb_image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "enrollments", force: :cascade do |t|
t.integer "section_id"
t.integer "student_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["section_id"], name: "index_enrollments_on_section_id"
t.index ["student_id"], name: "index_enrollments_on_student_id"
end
create_table "professors", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "status", default: 0
t.integer "department_id"
t.text "bio"
t.index ["department_id"], name: "index_professors_on_department_id"
end
create_table "sections", force: :cascade do |t|
t.integer "number"
t.integer "max_enrollment"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "professor_id"
t.integer "course_id"
t.string "room"
t.index ["course_id"], name: "index_sections_on_course_id"
t.index ["professor_id", "course_id"], name: "index_sections_on_professor_id_and_course_id", unique: true
t.index ["professor_id"], name: "index_sections_on_professor_id"
end
create_table "students", force: :cascade do |t|
t.string "name"
t.decimal "gpa"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "name"
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "roles"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
enrollment belongs_to user, there is no need to use each on single record rather it will throw error. You can use below code.
<% course.sections.each do |section| %>
<% section.enrollments.each do |enrollment| %>
<p><% enrollment.student.name %></p>
<% end %>
<% end %>
Sean's answer is almost correct but since enrollments belongs_to student
you would use the singular form enrollment.student. but more simply you can just call student from inside enrollments block.
<div class="col-md-8">
<h2 class="card-title"><%= #professor.name %></h2>
<% #courses_taught.each do |course| %>
<div class="card mb-4 card-header">
<img class="card-img-top" src="http://placehold.it/750x300" alt="Card image cap">
<h3 class="card-text"><%= course.title %></h3>
</div>
<div class="card-body">
<% course.sections.each do |section| %>
<% section.enrollments.each do |enrollment| %>
<p><% enrollment.student.name %></p>
<% end %>
<% end %>
</div>
<% end %>
</div>
<div class="col-md-8">
<h2 class="card-title"><%= #professor.name %></h2>
<% #courses_taught.each do |course| %>
<div class="card mb-4 card-header">
<img class="card-img-top" src="http://placehold.it/750x300" alt="Card image cap">
<h3 class="card-text"><%= course.title %></h3>
</div>
<div class="card-body">
<% course.sections.each do |section| %>
<% section.enrollments.each do |enrollment| %>
<p><% enrollment.student.name %></p>
<% end %>
<% end %>
</div>
<% end %>
</div>

Create categories in rails App

I would like to create categories in my app:
I got inspired by this question
But when #RailsGuy says: "Create some categories by categories controller and form (I don't think, I need to tell you that stuff, you are able to do it yourself)"
I felt lost...
How and where do I create my list of categories? dogs, cats, birds...
I saw that it could be done in the console but I will display a different pictures for each categories...
Here is my _form.html.slim
= simple_form_for #tuto do |f|
- if #tuto.errors.any?
#error_explanation
h2 = "#{pluralize(#tuto.errors.count, "error")} prohibited this tuto from being saved:"
ul
- #tuto.errors.full_messages.each do |message|
li = message
= f.hidden_field :user_id, value: current_user.id
= f.input :title
= f.collection_select :category_id, Category.all, :id, :name, {prompt: "Choose Category"}
= f.input :content, as: :text, input_html: { rows: "15" }
= f.button :submit, "Save"
my models:
tuto_model.rb
class Tuto < ActiveRecord::Base
acts_as_votable
belongs_to :user
belongs_to :category
validates :category, presence: true
end
categoty_model.rb
class Category < ActiveRecord::Base
has_many :tutos
end
schema.rb
ActiveRecord::Schema.define(version: 20160920133801) do
create_table "categories", force: :cascade do |t|
t.string "name"
t.text "description"
t.string "image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "tutos", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "title"
t.text "content"
t.integer "user_id"
t.integer "category_id"
end
add_index "tutos", ["user_id"], name: "index_tutos_on_user_id"
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "first_name"
t.string "last_name"
t.boolean "admin"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
create_table "votes", force: :cascade do |t|
t.integer "votable_id"
t.string "votable_type"
t.integer "voter_id"
t.string "voter_type"
t.boolean "vote_flag"
t.string "vote_scope"
t.integer "vote_weight"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope"
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope"
end
thanks a lot for your help
Have the pictues stored in assets. And in the form/view use a conditional?:
<% if tuto.category == dog %>
<%= image_tag 'dog.jpg' %>
<% end %>
Something like that?
Steve.
The other post says to use the controller and form to create new categories. If you used scaffold to create the model Category, you'll have the new & create action in the controller and a new.html.erb and index.html.erb (or.slim if you're using that).
You can create your categories in there, then select one in your Tuto model.
Make sense?
Steve.

2 kind of user Rails with Devise

This is really a noob question but I've search a lot and didn't find nothing for my solution.
A have a application with 2 kind of user. Customer and Contractor. I try with devise to build both and that work I can sign in contractor and same with customer all is good in the db etc. But some things don't work.
First I can't add company name in the sign in form for the contractor(I already did that a lot but know don't work) I make the migration etc but can't show the in the sign in form. I have no error just no show.
Finally I try to make the customer build the project and have his Id with the
current_cutomer.projects.build(project_params)
and I get a error about argument etc.
Sry for my english
projects_controller.rb
class ProjectsController < ApplicationController
before_action :find_project, only: [:show, :quote, :edit, :update]
before_action :authenticate_cus!, except: [:index, :show]
def home
end
def index
#projects = Project.all.order("created_at DESC")
end
def show
end
def quote
end
def new
#project = current_customer.projects.create
end
def create
#project = current_customer.projects.create(project_params)
if #project.save
redirect_to #project
else
render 'new'
end
end
def edit
end
def update
if #project.update(project_params)
redirect_to #project
else
render 'edit'
end
end
private
def project_params
params.require(:project).permit(:name, :description, :date, :budget, :category_id, :location, :image)
end
def find_project
#project = Project.find(params[:id])
end
end
schema.rb
ActiveRecord::Schema.define(version: 20160305071807) do
create_table "active_admin_comments", force: :cascade do |t|
t.string "namespace"
t.text "body"
t.string "resource_id", null: false
t.string "resource_type", null: false
t.string "author_type"
t.integer "author_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id"
add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace"
add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id"
create_table "admin_users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "admin_users", ["email"], name: "index_admin_users_on_email", unique: true
add_index "admin_users", ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true
create_table "categories", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "contractors", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "company_name"
end
add_index "contractors", ["email"], name: "index_contractors_on_email", unique: true
add_index "contractors", ["reset_password_token"], name: "index_contractors_on_reset_password_token", unique: true
create_table "customers", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "customers", ["email"], name: "index_customers_on_email", unique: true
add_index "customers", ["reset_password_token"], name: "index_customers_on_reset_password_token", unique: true
create_table "projects", force: :cascade do |t|
t.string "name"
t.text "description"
t.integer "budget"
t.date "date"
t.string "location"
t.integer "category_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.integer "customer_id"
end
add_index "projects", ["category_id"], name: "index_projects_on_category_id"
add_index "projects", ["customer_id"], name: "index_projects_on_customer_id"
end
form for the contractor
<h2>Sign up</h2>
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= f.error_notification %>
<h1>New Contractor</h1>
<div class="form-inputs">
<%= f.input :company_name, required: true, autofocus: true %>
<%= f.input :email, required: true %>
<%= f.input :password, required: true, hint: ("#{#minimum_password_length} characters minimum" if #minimum_password_length) %>
<%= f.input :password_confirmation, required: true %>
</div>
<div class="form-actions">
<%= f.button :submit, "Sign up" %>
</div>
<% end %>
<%= render "contractors/shared/links" %>
Finally I did two user model with devise and in the application controller I wrote
devise_group :user, contains: [:customer, :company]
Now I can use
#project = current_user.projects.build(project_params)
Everything Is ok and just need to give the permissions.

How should i show monthly generated tickets through chartkick

I am using rails 4, and I want to show monthly ticket generated through pie charts. Can anybody help?
Schema:
create_table "tickets", force: :cascade do |t|
t.integer "store_id"
t.integer "vendor_id"
t.datetime "ticket_date"
t.datetime "deadline"
t.text "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "ticket_no"
t.string "vendor_name"
t.string "user_id"
t.integer "issue_id"
t.integer "category_id"
t.boolean "completed", default: false
end
My ticket.rb contains:
def self.category_count(user,category)
if user.vendor.nil?
category.tickets.where('store_id = ?', user.store.id)
else
category.tickets.where('vendor_id = ?', user.vendor.id)
end
end
def self.ticket_count(user,ticket)
if user.vendor.nil?
ticket.tickets.where('store_id = ?', user.store.id)
else
ticket.tickets.where('vendor_id = ?', user.vendor.id)
end
end
view:
tickets:
index.html.erb file is:
<% data = {} %>
<% for category in Category.all %>
<% data[:"#{category.name}"] = Ticket.category_count(current_user,category).count %>
<% end %>
<%= pie_chart(data) %>
I would probably start by moving this into a view helper method such as:
def pie_chart_data(user)
Hash[*Category.all.map { |c| [c.name, Ticket.category_count(user, c).count] }]
end
You could then call this in your view
<%= pie_chart(pie_chart_data(current_user)) %>

Ordering messages in conversation - rails

I'm using a gem called mailboxer to allow users to send messages among each other:
Here is what I have in my conversations controller:
class ConversationsController < ApplicationController
...
private
def mailbox
#mailbox ||= current_user.mailbox
end
def conversation
#conversation ||= mailbox.conversations.find(params[:id])
end
def conversation_params(*keys)
fetch_params(:conversation, *keys)
end
def message_params(*keys)
fetch_params(:message, *keys)
end
def fetch_params(key, *subkeys)
params[key].instance_eval do
case subkeys.size
when 0 then self
when 1 then self[subkeys.first]
else subkeys.map{|k| self[k] }
end
end
end
end
And this is what I have in my conversations show view:
<p> <%= conversation.subject %> </p>
<%= content_tag_for(:p, conversation.receipts_for(current_user)) do |receipt| %>
<% message = receipt.message %>
<p>
<%= message.body %>
</p>
<% end %>
<%= render 'messages/form', conversation: conversation %>
Which works, but the messages are all scrambled. How do I order the messages of the conversation by when they were created?
My schema pertaining to mailboxer:
create_table "receipts", force: true do |t|
t.integer "receiver_id"
t.string "receiver_type"
t.integer "notification_id", null: false
t.boolean "is_read", default: false
t.boolean "trashed", default: false
t.boolean "deleted", default: false
t.string "mailbox_type", limit: 25
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "receipts", ["notification_id"], name: "index_receipts_on_notification_id"
create_table "conversations", force: true do |t|
t.string "subject", default: ""
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "notifications", force: true do |t|
t.string "type"
t.text "body"
t.string "subject", default: ""
t.integer "sender_id"
t.string "sender_type"
t.integer "conversation_id"
t.boolean "draft", default: false
t.datetime "updated_at", null: false
t.datetime "created_at", null: false
t.integer "notified_object_id"
t.string "notified_object_type"
t.string "notification_code"
t.string "attachment"
t.boolean "global", default: false
t.datetime "expires"
end
add_index "notifications", ["conversation_id"], name: "index_notifications_on_conversation_id"
I think you just need to order the receipts like this:
<%= content_tag_for(:p, conversation.receipts_for(current_user).order(:created_at)) do |receipt| %>

Resources