Commit 76355015 by Quang Vinh Nguyen

basic apply

parent df57c21f
...@@ -67,6 +67,8 @@ group :development do ...@@ -67,6 +67,8 @@ group :development do
gem 'spring' gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0' gem 'spring-watcher-listen', '~> 2.0.0'
gem 'pry' gem 'pry'
gem "better_errors"
gem "binding_of_caller"
end end
group :test do group :test do
......
...@@ -54,7 +54,13 @@ GEM ...@@ -54,7 +54,13 @@ GEM
bcrypt (3.1.12-java) bcrypt (3.1.12-java)
bcrypt (3.1.12-x64-mingw32) bcrypt (3.1.12-x64-mingw32)
bcrypt (3.1.12-x86-mingw32) bcrypt (3.1.12-x86-mingw32)
better_errors (2.4.0)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
rack (>= 0.9.0)
bindex (0.5.0) bindex (0.5.0)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
bootsnap (1.3.0) bootsnap (1.3.0)
msgpack (~> 1.0) msgpack (~> 1.0)
bootsnap (1.3.0-java) bootsnap (1.3.0-java)
...@@ -94,6 +100,7 @@ GEM ...@@ -94,6 +100,7 @@ GEM
dry-validation (>= 0.10.4) dry-validation (>= 0.10.4)
crass (1.0.4) crass (1.0.4)
database_cleaner (1.7.0) database_cleaner (1.7.0)
debug_inspector (0.0.3)
deep_merge (1.2.1) deep_merge (1.2.1)
devise (4.4.3) devise (4.4.3)
bcrypt (~> 3.0) bcrypt (~> 3.0)
...@@ -371,6 +378,8 @@ PLATFORMS ...@@ -371,6 +378,8 @@ PLATFORMS
x86-mswin32 x86-mswin32
DEPENDENCIES DEPENDENCIES
better_errors
binding_of_caller
bootsnap (>= 1.1.0) bootsnap (>= 1.1.0)
bootstrap bootstrap
byebug byebug
......
class EntriesController < ApplicationController
before_action :set_entry, only: [:show, :edit, :update, :destroy]
# GET /entries
# GET /entries.json
def index
@entries = Entry.all
end
# GET /entries/1
# GET /entries/1.json
def show
end
# GET /entries/new
def new
@entry = Entry.new
end
# GET /entries/1/edit
def edit
end
# POST /entries
# POST /entries.json
def create
@entry = Entry.new(entry_params)
@job = Job.find(params[:job_id])
@user = User.find_by( email: params[:entry][:entry_email]) ||
User.create( name: params[:entry][:entry_name],
email: params[:entry][:entry_email],
password: 'password',
password_confirmation: 'password')
@entry.user_id = @user.id
@entry.job_id = @job.id
respond_to do |format|
if @entry.save
format.html { redirect_to @entry, notice: 'Entry was successfully created.' }
format.json { render :show, status: :created, location: @entry }
else
format.html { render :new }
format.json { render json: @entry.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /entries/1
# PATCH/PUT /entries/1.json
def update
respond_to do |format|
if @entry.update(entry_params)
format.html { redirect_to @entry, notice: 'Entry was successfully updated.' }
# format.json { render :show, status: :ok, location: @entry }
else
format.html { render :edit }
# format.json { render json: @entry.errors, status: :unprocessable_entity }
end
end
end
# DELETE /entries/1
# DELETE /entries/1.json
def destroy
@entry.destroy
respond_to do |format|
format.html { redirect_to entries_url, notice: 'Entry was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_entry
@entry = Entry.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def entry_params
params.require(:entry).permit(:entry_name, :entry_email)
end
end
module EntriesHelper
end
class Entry < ApplicationRecord class Entry < ApplicationRecord
belongs_to :user, foreign_key: 'user_id' belongs_to :user, foreign_key: 'user_id'
belongs_to :job, foreign_key: 'job_id' belongs_to :job, foreign_key: 'job_id'
validates :entry_name, presence: true
validates :entry_email, presence: true
end end
...@@ -11,6 +11,10 @@ class Job < ApplicationRecord ...@@ -11,6 +11,10 @@ class Job < ApplicationRecord
dependent: :destroy dependent: :destroy
has_many :industries, through: :industries_jobs has_many :industries, through: :industries_jobs
has_many :entries, foreign_key: 'job_id',
dependent: :destroy
has_many :users, through: :entries
has_many :entries, dependent: :destroy has_many :entries, dependent: :destroy
has_many :favorite_jobs, dependent: :destroy has_many :favorite_jobs, dependent: :destroy
......
...@@ -2,19 +2,23 @@ class User < ApplicationRecord ...@@ -2,19 +2,23 @@ class User < ApplicationRecord
# Include default devise modules. Others available are: # Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable # :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :recoverable, :rememberable, :validatable,
:confirmable :confirmable
has_many :entries, dependent: :destroy has_many :entries, dependent: :destroy
has_many :favorite_jobs, dependent: :destroy has_many :favorite_jobs, dependent: :destroy
has_many :entries, foreign_key: 'user_id',
dependent: :destroy
has_many :jobs, through: :entries
validates :name, presence: true, length: { maximum: 255 } validates :name, presence: true, length: { maximum: 255 }
validates :prefix, presence: true # validates :prefix, presence: true
VALID_PHONE_REGEX = /\A^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}\z/ # VALID_PHONE_REGEX = /\A^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}\z/
validates :phone, length: { maximum: 50 }, # validates :phone, length: { maximum: 50 },
format: { with: VALID_PHONE_REGEX } # format: { with: VALID_PHONE_REGEX }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, length: { maximum: 255 }, validates :email, length: { maximum: 255 },
......
json.extract! entry, :id, :entry_name, :entry_email, :created_at, :updated_at
json.url entry_url(entry, format: :json)
<%= form_with(model: entry, local: true) do |form| %>
<% if entry.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(entry.errors.count, "error") %> prohibited this entry from being saved:</h2>
<ul>
<% entry.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= hidden_field_tag :job_id, @job.id %>
<%= form.label :name %><br>
<%= form.text_field :entry_name, class: 'form-control' %><br>
<%= form.label :email %><br>
<%= form.email_field :entry_email, class: 'form-control' %><br>
<%= form.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>
<% provide(:button_text, 'Save') %>
<h1>Editing Entry</h1>
<%= render 'form', entry: @entry %>
<%= link_to 'Show', @entry %> |
<%= link_to 'Back', entries_path %>
<p id="notice"><%= notice %></p>
<h1>Entries</h1>
<table>
<thead>
<tr>
<th>Entry name</th>
<th>Entry email</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @entries.each do |entry| %>
<tr>
<td><%= entry.entry_name %></td>
<td><%= entry.entry_email %></td>
<td><%= link_to 'Show', entry %></td>
<td><%= link_to 'Edit', edit_entry_path(entry) %></td>
<td><%= link_to 'Destroy', entry, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Entry', new_entry_path %>
json.array! @entries, partial: 'entries/entry', as: :entry
<% provide(:button_text, 'Apply') %>
<% @job = Job.find(params[:job_id]) %>
<h3>Id: <%= @job.id %> -- Job_title: <%= @job.title %> </h3>
<%= render 'form', entry: @entry %>
<p id="notice"><%= notice %></p>
<% @job = Job.find(@entry.job_id) %>
<h3>Id: <%= @job.id %> -- Job_title: <%= @job.title %> </h3>
<p>
<strong>Name:</strong>
<%= @entry.entry_name %>
</p>
<p>
<strong>Email:</strong>
<%= @entry.entry_email %>
</p>
<%= link_to 'Edit', edit_entry_path(@entry) %> |
<%= link_to 'Back', entries_path %>
json.partial! "entries/entry", entry: @entry
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
<p> <p>
<%= @job.description %> <%= @job.description %>
</p> </p>
<%= link_to "Apply", apply_path(job_id: @job.id),
class: "btn btn-primary" %>
</section> </section>
</aside> </aside>
</div> </div>
...@@ -11,6 +11,15 @@ ...@@ -11,6 +11,15 @@
<li class="nav-item active"> <li class="nav-item active">
<%= link_to 'City', city_jobs_path, class: 'nav-link' %> <%= link_to 'City', city_jobs_path, class: 'nav-link' %>
</li> </li>
<% if user_signed_in? %>
<li class="nav-item active">
<%= link_to 'Logout', destroy_user_session_path, method: :delete %>
</li>
<% else %>
<li class="nav-item active" >
<%= link_to 'Login', new_user_session_path %>
</li>
<% end %>
</ul> </ul>
</div> </div>
</nav> </nav>
Rails.application.routes.draw do Rails.application.routes.draw do
root to: 'jobs#home' root to: 'jobs#home'
resources :entries
get '/apply', to: 'entries#new'
resources :jobs do resources :jobs do
collection do collection do
......
...@@ -3,8 +3,11 @@ class CreateEntries < ActiveRecord::Migration[5.2] ...@@ -3,8 +3,11 @@ class CreateEntries < ActiveRecord::Migration[5.2]
create_table :entries do |t| create_table :entries do |t|
t.references :user, foreign_key: true t.references :user, foreign_key: true
t.references :job, foreign_key: true t.references :job, foreign_key: true
t.string :entry_name
t.string :entry_email
t.timestamps t.timestamps
end end
add_index :entries, [:user_id, :job_id], unique: true
end end
end end
...@@ -50,9 +50,12 @@ ActiveRecord::Schema.define(version: 2018_06_19_011959) do ...@@ -50,9 +50,12 @@ ActiveRecord::Schema.define(version: 2018_06_19_011959) do
create_table "entries", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| create_table "entries", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
t.bigint "user_id" t.bigint "user_id"
t.bigint "job_id" t.bigint "job_id"
t.string "entry_name"
t.string "entry_email"
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["job_id"], name: "index_entries_on_job_id" t.index ["job_id"], name: "index_entries_on_job_id"
t.index ["user_id", "job_id"], name: "index_entries_on_user_id_and_job_id", unique: true
t.index ["user_id"], name: "index_entries_on_user_id" t.index ["user_id"], name: "index_entries_on_user_id"
end end
......
require 'rails_helper'
# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to specify the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator. If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails. There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.
#
# Compared to earlier versions of this generator, there is very limited use of
# stubs and message expectations in this spec. Stubs are only used when there
# is no simpler way to get a handle on the object needed for the example.
# Message expectations are only used when there is no simpler way to specify
# that an instance is receiving a specific message.
#
# Also compared to earlier versions of this generator, there are no longer any
# expectations of assigns and templates rendered. These features have been
# removed from Rails core in Rails 5, but can be added back in via the
# `rails-controller-testing` gem.
RSpec.describe EntriesController, type: :controller do
# This should return the minimal set of attributes required to create a valid
# Entry. As you add validations to Entry, be sure to
# adjust the attributes here as well.
let(:valid_attributes) {
skip("Add a hash of attributes valid for your model")
}
let(:invalid_attributes) {
skip("Add a hash of attributes invalid for your model")
}
# This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# EntriesController. Be sure to keep this updated too.
let(:valid_session) { {} }
describe "GET #index" do
it "returns a success response" do
entry = Entry.create! valid_attributes
get :index, params: {}, session: valid_session
expect(response).to be_success
end
end
describe "GET #show" do
it "returns a success response" do
entry = Entry.create! valid_attributes
get :show, params: {id: entry.to_param}, session: valid_session
expect(response).to be_success
end
end
describe "GET #new" do
it "returns a success response" do
get :new, params: {}, session: valid_session
expect(response).to be_success
end
end
describe "GET #edit" do
it "returns a success response" do
entry = Entry.create! valid_attributes
get :edit, params: {id: entry.to_param}, session: valid_session
expect(response).to be_success
end
end
describe "POST #create" do
context "with valid params" do
it "creates a new Entry" do
expect {
post :create, params: {entry: valid_attributes}, session: valid_session
}.to change(Entry, :count).by(1)
end
it "redirects to the created entry" do
post :create, params: {entry: valid_attributes}, session: valid_session
expect(response).to redirect_to(Entry.last)
end
end
context "with invalid params" do
it "returns a success response (i.e. to display the 'new' template)" do
post :create, params: {entry: invalid_attributes}, session: valid_session
expect(response).to be_success
end
end
end
describe "PUT #update" do
context "with valid params" do
let(:new_attributes) {
skip("Add a hash of attributes valid for your model")
}
it "updates the requested entry" do
entry = Entry.create! valid_attributes
put :update, params: {id: entry.to_param, entry: new_attributes}, session: valid_session
entry.reload
skip("Add assertions for updated state")
end
it "redirects to the entry" do
entry = Entry.create! valid_attributes
put :update, params: {id: entry.to_param, entry: valid_attributes}, session: valid_session
expect(response).to redirect_to(entry)
end
end
context "with invalid params" do
it "returns a success response (i.e. to display the 'edit' template)" do
entry = Entry.create! valid_attributes
put :update, params: {id: entry.to_param, entry: invalid_attributes}, session: valid_session
expect(response).to be_success
end
end
end
describe "DELETE #destroy" do
it "destroys the requested entry" do
entry = Entry.create! valid_attributes
expect {
delete :destroy, params: {id: entry.to_param}, session: valid_session
}.to change(Entry, :count).by(-1)
end
it "redirects to the entries list" do
entry = Entry.create! valid_attributes
delete :destroy, params: {id: entry.to_param}, session: valid_session
expect(response).to redirect_to(entries_url)
end
end
end
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the EntriesHelper. For example:
#
# describe EntriesHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe EntriesHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end
require 'rails_helper'
RSpec.describe "Entries", type: :request do
describe "GET /entries" do
it "works! (now write some real specs)" do
get entries_path
expect(response).to have_http_status(200)
end
end
end
require "rails_helper"
RSpec.describe EntriesController, type: :routing do
describe "routing" do
it "routes to #index" do
expect(:get => "/entries").to route_to("entries#index")
end
it "routes to #new" do
expect(:get => "/entries/new").to route_to("entries#new")
end
it "routes to #show" do
expect(:get => "/entries/1").to route_to("entries#show", :id => "1")
end
it "routes to #edit" do
expect(:get => "/entries/1/edit").to route_to("entries#edit", :id => "1")
end
it "routes to #create" do
expect(:post => "/entries").to route_to("entries#create")
end
it "routes to #update via PUT" do
expect(:put => "/entries/1").to route_to("entries#update", :id => "1")
end
it "routes to #update via PATCH" do
expect(:patch => "/entries/1").to route_to("entries#update", :id => "1")
end
it "routes to #destroy" do
expect(:delete => "/entries/1").to route_to("entries#destroy", :id => "1")
end
end
end
require 'rails_helper'
RSpec.describe "entries/edit", type: :view do
before(:each) do
@entry = assign(:entry, Entry.create!(
:entry_name => "MyString",
:entry_email => "MyString"
))
end
it "renders the edit entry form" do
render
assert_select "form[action=?][method=?]", entry_path(@entry), "post" do
assert_select "input[name=?]", "entry[entry_name]"
assert_select "input[name=?]", "entry[entry_email]"
end
end
end
require 'rails_helper'
RSpec.describe "entries/index", type: :view do
before(:each) do
assign(:entries, [
Entry.create!(
:entry_name => "Entry Name",
:entry_email => "Entry Email"
),
Entry.create!(
:entry_name => "Entry Name",
:entry_email => "Entry Email"
)
])
end
it "renders a list of entries" do
render
assert_select "tr>td", :text => "Entry Name".to_s, :count => 2
assert_select "tr>td", :text => "Entry Email".to_s, :count => 2
end
end
require 'rails_helper'
RSpec.describe "entries/new", type: :view do
before(:each) do
assign(:entry, Entry.new(
:entry_name => "MyString",
:entry_email => "MyString"
))
end
it "renders new entry form" do
render
assert_select "form[action=?][method=?]", entries_path, "post" do
assert_select "input[name=?]", "entry[entry_name]"
assert_select "input[name=?]", "entry[entry_email]"
end
end
end
require 'rails_helper'
RSpec.describe "entries/show", type: :view do
before(:each) do
@entry = assign(:entry, Entry.create!(
:entry_name => "Entry Name",
:entry_email => "Entry Email"
))
end
it "renders attributes in <p>" do
render
expect(rendered).to match(/Entry Name/)
expect(rendered).to match(/Entry Email/)
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment