I'm trying to set a has_many trough relationship and I'm new to this
#models/partner.rb
class Partner < ActiveRecord::Base
has_many :cards_partners
has_many :cards, through: :cards_partners
#models/card.rb
class Card < ActiveRecord::Base
has_many :cards_partners
has_many :partners, through: :cards_partners
#models/cards_partner.rb
class CardsPartner < ActiveRecord::Base
belongs_to :card
belongs_to :partner
And I specified the controllers
#controllers/cards_controller.rb
before_action :set_card, only: [:show, :edit, :update, :destroy]
def show
#user = #card.user
#partners = #card.partners.order(lastname: :desc)
#partner = #card.partners.new #because I have a modal to create new Partner too
#address is in a polymorphic table. I have to refactor the if-else
if #card.address.street.blank? && #card.address.city.blank?
#address = #user.address
else
#address = #card.address
end
end
def create
#card = current_user.cards.new(card_params)
respond_to do |format|
if #card.save
format.html { redirect_to #card, notice: 'Card was successfully created.' }
format.json { render :show, status: :created, location: #card }
else
format.html { render :new }
format.json { render json: #card.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #card.update(card_params)
format.html { redirect_to #card, notice: 'Card was successfully updated.' }
format.json { render :show, status: :ok, location: #card }
else
format.html { render :edit }
format.json { render json: #card.errors, status: :unprocessable_entity }
end
end
end
private
def set_card
#card = Card.find(params[:id])
end
def card_params
params.require(:card).permit(partner_ids: [])
end
#controllers/partners_controller.rb
def partner_params
params.require(:partner).permit(card_ids: [])
end
My join table cards_partners is properly set.
To sum up the logic, a User can create Cards and add Partners to this Card.
I set a has_many through between Cards and Partners because I want User to be able to assign already Created Partners to multiple Cards.
I have inside my cards#show view a partial that shows all the partners, and a link to add a new one to this card.
I define my #partners inside my card#show action with (not sure about this since no join specified):
#partners = #card.partners.order(lastname: :desc)
I can't figure how to specify the card and then creating a new partner from card#show view using the link new_partner_path.
Any help would be really appreciated.
Thank you a lot
Related
Why does the error occur?
There hasen't been an adquate/similar solution for my problem. I just could find some tips and tricks here but now I am stuck.
We have a course management system. You can add new coures, participants and persons among other things. I had to change the database. Now there is a persons table, too. Earlier all informations about persons respectively participants where just saved in the participants table. Now when a new participant is added the persons table is involved.
We want to add a new participant of a course. I adjusted the new action in the participants controller and I was hoping passing all data like in the old way. The old way was working to add a new participant.
Earlier the way was: course > new participant form
Now it is: course > search for a person to use it in the form > new participant form
I think (better ways accepted) I just adjust the old code?! Below is my try.
The Error
NoMethodError in ParticipantsController#new undefined method `participants' for []:Array
occurs.
Here are the old classes:
Model Course
class Course < ActiveRecord::Base
has_many :participants
Model Participant
class Participant < ActiveRecord::Base
belongs_to :course
belongs_to :organization
belongs_to :function
ParticipantsController
class ParticipantsController < ApplicationController
....
def new
#course = Course.find(params[:course_id])
#participant = #course.participants.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #participant }
end
end
def create
#course = Course.find(params[:course_id])
#participant = #course.participants.new(params[:participant])
#course.updated_by = current_user.cn
#course.send(:create_version)
#course.tag_version(t(:participant_added))
#course.save!
respond_to do |format|
if #participant.save
format.html { redirect_to course_path(#participant.course), notice: 'Participant was successfully created.' }
format.json { render json: #participant, status: :created, location: #participant }
else
format.html { render action: "new" }
format.json { render json: #participant.errors, status: :unprocessable_entity }
end
end
end
When you look below at the course view snippet there is the old and new path to the form. Note that the person search is in between the course and the new participant form now.
**old** <%= link_to t(:add), new_course_participant_path(#course) %>
**new** <%= link_to t(:add), course_persons_path(#course, #person)%>
Here are the new classes
class Participant < ActiveRecord::Base
belongs_to :course
belongs_to :function
belongs_to :person
class Person < ActiveRecord::Base
has_many :participants
has_many :courses, through: :participants
Here are my adjustments in the ParticipantsController. My thoughts are maybe naive because I am still learning ruby on rails.
class ParticipantsController < ApplicationController
def new
#person = Person.find(params[:person_id])
#participant = Participant.find_by_person_id(params[:person_id])
#course= Course.find(:all, :conditions => {:id => #participant})
#participant = #course.participants.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #participant }
end
end
def create
#course= Course.find(params[:course_id])
#participant = #course.participants.new(params[:participant])
#course.updated_by = current_user.cn
#course.send(:create_version)
#course.tag_version(t(:participant_added))
#course.save!
respond_to do |format|
if #participant.save
format.html { redirect_to course_path(#participant.course), notice: 'Participant was successfully created.' }
format.json { render json: #participant, status: :created, location: #participant }
else
format.html { render action: "new" }
format.json { render json: #participant.errors, status: :unprocessable_entity }
end
end
end
Thanks in advance
Rewrite:
#person = Person.find(params[:person_id])
#participant = Participant.find_by_person_id(params[:person_id])
#course= Course.find(:all, :conditions => {:id => #participant})
#participant = #course.participants.build
To:
#person = Person.find(params[:person_id])
#course = Participant.find_by_person_id(params[:person_id]).course
#participant = #course.participants.build
Watch for out for exception in case Participant.find_by_person_id(params[:person_id]) returns a nil
I am making a sort of checklist section for my site. I have a model called commission that will contain data about a commissioning task. What I need to do is when a new commission entry is created I need to create a series of about 30 commission tasks that will link to it. A sort of checklist of predefined values for a person to go down through and check. What would be the best way to do this?
Here are my models and controller:
commission.rb
class Commission < ApplicationRecord
has_many :comtasks
belongs_to :project
belongs_to :user
accepts_nested_attributes_for :comtasks, allow_destroy: true
end
comtask.rb
class Comtask < ApplicationRecord
belongs_to :commission
belongs_to :user
end
commissions_controller.rb
class CommissionsController < ApplicationController
before_action :set_commission, only: [:show, :edit, :update, :destroy]
# GET /commissions
# GET /commissions.json
def index
#commissions = Commission.all
end
# GET /commissions/1
# GET /commissions/1.json
def show
end
# GET /commissions/new
def new
#commission = Commission.new
end
# GET /commissions/1/edit
def edit
end
# POST /commissions
# POST /commissions.json
def create
#commission = Commission.new(commission_params)
respond_to do |format|
if #commission.save
format.html { redirect_to #commission, notice: 'Commission was successfully created.' }
format.json { render :show, status: :created, location: #commission }
else
format.html { render :new }
format.json { render json: #commission.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /commissions/1
# PATCH/PUT /commissions/1.json
def update
respond_to do |format|
if #commission.update(commission_params)
format.html { redirect_to #commission, notice: 'Commission was successfully updated.' }
format.json { render :show, status: :ok, location: #commission }
else
format.html { render :edit }
format.json { render json: #commission.errors, status: :unprocessable_entity }
end
end
end
# DELETE /commissions/1
# DELETE /commissions/1.json
def destroy
#commission.destroy
respond_to do |format|
format.html { redirect_to commissions_url, notice: 'Commission was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_commission
#commission = Commission.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def commission_params
params.require(:commission).permit(:project_id, :user_id, :description, :objectname, :location, comtasks_attributes: [:id, :content, :notes])
end
end
Any thoughts or suggestions are appreciated.
below is the idea,
def create
#commission = Commission.create!(commission_params)
# use create not new to generate #commission.id value
# so comtask records can use the id value as reference
create_comtasks_job
# for comtask create I put in other method
respond_to do |format|
if #commission.save
format.html { redirect_to #commission, notice: 'Commission was successfully created.' }
format.json { render :show, status: :created, location: #commission }
else
format.html { render :new }
format.json { render json: #commission.errors, status: :unprocessable_entity }
end
end
end
def create_comtasks_job
# loop 30 tasks / or manual as follow
#commission.comtasks.build(content: 'content1',notes:'notes1')
#commission.comtasks.build(content: 'content2',notes:'notes2')
end
additional code for your model
make sure for your model has relation like sample below
for your model
class Commission < ActiveRecord::Base
has_many :comtasks
end
class Comtask < ActiveRecord::Base
belongs_to :commission
end
I've used this instructions for simply add score when a user creates a "solucion" (which is a kind of "answer" to a micropost). I have added the has_merit line to user.rb (user model).
I want to display the user points earned for that action at the show view.
show.html.erb (for solucion):
<h2><span class="red"><%= current_user.points %></span><br>Points</br></h2>
It displays 0 points...
point_rules.rb:
module Merit
class PointRules
include Merit::PointRulesMethods
def initialize
score 5, on: 'solucions#create'
end
end
end
When I create a solucion with the current_user (already saving the user_id index and identifier to solucion), This is what my rails server output shows...
Direct link to github gist:
https://gist.github.com/roadev/7b34fd67ab93c979fa48
Embed:
<script src="https://gist.github.com/roadev/7b34fd67ab93c979fa48.js"></script>
EDIT:
solucions_micropost.rb
class SolucionsController < ApplicationController
before_action :set_solucion, only: [:show, :edit, :update, :destroy]
def index
#solucions = Solucion.all
end
def show
end
def new
#solucion = current_user.solucions.build
end
def edit
end
def create
#solucion = current_user.solucions.build(solucion_params)
respond_to do |format|
if #solucion.save
format.html { redirect_to #solucion, notice: 'Solucion was successfully created.' }
format.json { render action: 'show', status: :created, location: #solucion }
else
format.html { render action: 'new' }
format.json { render json: #solucion.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #solucion.update(solucion_params)
format.html { redirect_to #solucion, notice: 'Solucion was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #solucion.errors, status: :unprocessable_entity }
end
end
end
def destroy
#solucion.destroy
respond_to do |format|
format.html { redirect_to solucions_url }
format.json { head :no_content }
end
end
private
def set_solucion
#solucion = Solucion.find(params[:id])
end
def current_micropost
#solucion = microposts.find_by(id: params[:id])
end
def solucion_params
params.require(:solucion).permit(:solucion, :image, :micropost_id)
end
end
user.rb:
class User < ActiveRecord::Base
has_many :dreams
has_many :microposts
has_many :solucions
has_merit
end
I had a problem with a migration when I installed the merit gem.
I'm trying to create a form that allow called submits. I've got all the appropriate MVC created. I've then created a model called questions that works and am using active admin to allow admin users to add new questions to the form as they see fit. When I test submitting the form I get this error
undefined method `each' for nil:NilClass
#submit = Submit.new(submit_params)
#submit.save
params[:submit][:question_ids].each do |question_id|
#question = Question.find(question_id)
#submit.questions << #question
end
Here's my submits controller:
class SubmitsController < ApplicationController
before_action :set_submit, only: [:show, :edit, :update, :destroy]
def index
#submits = Submit.all
end
def show
end
def new
#submit = Submit.new
#questions = Question.all
end
def edit
end
def create
#submit = Submit.new(submit_params)
#submit.save
params[:submit][:question_ids].each do |question_id|
#question = Question.find(question_id)
#submit.questions << #question
end
respond_to do |format|
if #submit.save
format.html { redirect_to #submit, notice: 'Application was successfully created.' }
format.json { render :show, status: :created, location: #submit }
else
format.html { render :new }
format.json { render json: #submit.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #submit.update(submit_params)
format.html { redirect_to #submit, notice: 'Application was successfully updated.' }
format.json { render :show, status: :ok, location: #submit }
else
format.html { render :edit }
format.json { render json: #submit.errors, status: :unprocessable_entity }
end
end
end
def destroy
#submit.destroy
respond_to do |format|
format.html { redirect_to submits_url, notice: 'Submit was successfully destroyed.' }
format.json { head :no_content }
end
end
Here's my Submit and Question model:
Submit:
class Submit < ActiveRecord::Base
has_and_belongs_to_many :questions
belongs_to :user
end
Question:
class Question < ActiveRecord::Base
has_and_belongs_to_many :submits
end
I'm sure it's some kind of syntax error in my controller but I don't know what. Still pretty new to using join tables. Any help/explanation would be very appreciated.
Thanks!
You don't need this
params[:submit][:question_ids].each do |question_id|
#question = Question.find(question_id)
#submit.questions << #question
end
I don't see your submit params but if you add question ids to the permitted parameters then rails will build the entry in the join table on it's own.
def submit_params
params.require(:submit).permit(:user_id, question_ids: [])
end
I have 2 models user and order
in the user model i have the following
class User < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
has_many orders
end
in the orders model, i have
class Order < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
belongs_to user
end
in the orders controller i have
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy]
def create
#user = User.find(params[:user_id])
#order = #user.orders.build(order_params)
respond_to do |format|
if #order.save
format.html { redirect_to #order, notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: #order }
else
format.html { render action: 'new' }
format.json { render json: #orders.errors, status: :unprocessable_entity }
end
end
end
private
def order_params
params[:order].permit( :order_title, :propose_amount,
:terms,:users_attributes => [:user_id])
end
end
on creating the order, i keep getting the error below
Couldn't find user without an ID
and the following line is higlighted as the line of error
#user = User.find(params[:user_id])
does anyone knows where am heading wrong?