Reputation: 2683
A basic overview of my app. There is currently two models. A jobs model and a clients model. Both models have a has_and_belongs_to_many
relationship as I intended to allow the user to create a client entry and then assign them one or many jobs.
Here are both of my models.
Clients -
class Client < ActiveRecord::Base
has_and_belongs_to_many :job
end
Jobs -
class Job < ActiveRecord::Base
has_and_belongs_to_many :client
end
I have been doing some research and I think im right in thinking that the relationship needs a foreign key to function so have added a client_id
column & a job_id
column to my database.
The clients page is currently working and here is my controller for that.
class ClientsController < ApplicationController
def index
@clients = Client.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @clients }
end
end
# GET /Clients/1
# GET /Clients/1.json
def show
@clients = Client.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @clients }
end
end
# GET /Clients/new
# GET /Clients/new.json
def new
@clients = Client.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @clients }
end
end
# GET /Clients/1/edit
def edit
@clients = Client.find(params[:id])
end
def create
@clients = Client.new(params[:client])
respond_to do |format|
if @clients.save
format.html { redirect_to @clients, notice: 'Client was successfully created.' }
format.json { render json: @clients, status: :created, location: @clients }
else
format.html { render action: "new" }
format.json { render json: @clients.errors, status: :unprocessable_entity }
end
end
end
# PUT /Clients/1
# PUT /Clients/1.json
def update
@clients = Client.find(params[:id])
respond_to do |format|
if @clients.update_attributes(params[:client])
format.html { redirect_to @clients, notice: 'Client was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @clients.errors, status: :unprocessable_entity }
end
end
end
# DELETE /Clients/1
# DELETE /Clients/1.json
def destroy
@clients = Client.find(params[:id])
@clients.destroy
respond_to do |format|
format.html { redirect_to :clients , notice: 'Client was successfully removed.'}
format.json { head :no_content }
end
end
def details
@clients = Client.find_by_id(params[:id])
@jobs = Client.job
end
end
And here's what I currently have for my jobs controller.
class JobsController < ApplicationController
def index
@jobs = Job.find(:all)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @job }
end
end
def new
@jobs = Job.new
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @job }
end
end
def create
@jobs = Job.new(params[:job])
@cients = Client.find = Client.find(params[:id])
respond_to do |format|
if @jobs.save
format.html { redirect_to(@jobs,
:notice => 'Job was successfully created.') }
format.xml { render :xml => @jobs,
:status => :created, :location => @Job }
else
format.html { render :action => "new" }
format.xml { render :xml => @jobs.errors,
:status => :unprocessable_entity }
end
end
end
end
In my jobs form I was given thr following code which added a drop down with all the created clients.
<%= select("job", "client_id", Client.all.collect {|c| [ c.name, c.id ] }, {:include_blank => 'None'})%>
When I press save though. I recieve the following error.
unknown attribute: client_id
Application Trace | Framework Trace | Full Trace
app/controllers/jobs_controller.rb:22:in `new'
app/controllers/jobs_controller.rb:22:in `create'
I assume this is because I need to define a way of finding the client_id in my job creation as well as specifying one in my client creation.
This is my first rails app though so im not quite sure how.
Any help would be greatly appreciated.
Upvotes: 0
Views: 198
Reputation: 239240
Your jobs
table doesn't have a client_id
, nor should it. You need to create a junction table to facilitate a many-to-many relationship. It should be called clients_jobs
and contain an integer client_id
and job_id
.
There is a lot more wrong here. Here are just the things I caught at a casual glance:
This line:
@cients = Client.find = Client.find(params[:id])
should be:
@cients = Client.find(params[:id])
Pluralization is important in Rails. A client doesn't have many "job". It has many jobs. Your models should reflect this:
class Client < ActiveRecord::Base
has_and_belongs_to_many :jobs
end
class Job < ActiveRecord::Base
has_and_belongs_to_many :clients
end
You'll need to create a junction table via a migration, which is where your foreign keys will exist:
$ rails g migration AddClientsJobsTable
In index
and new
, you first create @jobs = Job.new
and then you render it via :xml => @job
. Again, pluralization is important. You need @job = Job.new
. You have the same problem in create
, except you've dropped the 's' and capitalized the 'J': :location => @Job }
You can't do that in programming. Case and spelling both matter.
Job.find(:all)
or Client.all
: Pick one. Don't mix find :all
and .all
.
@clients = Client.find(params[:id])
. You're finding a single specific Client, not a collection of clients. Your variable should be called @client
. This is not an error, but it is seriously ugly.Upvotes: 1
Reputation: 2573
pluralize your jobs and clients in your associations. I.E
has_many_and_belongs_to :jobs
has_many_and_belongs_to :clients
And if you do not use the alternative to this many-to-many associations with the ActiveRecord :through method (the alternative to HMABT) You must create the join table yourself which is a table of job_id's and client_id's.
Upvotes: 1