Couldn't find model without an ID (rails4 with strong parameters) - ruby-on-rails

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?

Related

Trying to render categories in my product view in rails

I'm trying to render on my product show/index page what category a specific product belongs to. I don't know if I need to create a join table or if the way that I have set up the models is good enough. I've linked my product model and controllers, and have done the same for my categories.
Product.rb
class Product < ActiveRecord::Base
has_many :orders
belongs_to :categories
validates :name, :price, presence: true
mount_uploader :image, ImageUploader
end
Categories.rb
class Category < ActiveRecord::Base
has_many :products
has_many :users, through: :categories
validates :name, presence: true
TITLE = %w{ Electronics Home Garden Lifestyle }
end
Categories_controller.rb
class CategoriesController < ApplicationController
before_action :set_category, only: [:show, :edit, :update, :destroy]
def index
#categories = Category.all
#products = Product.all.order("created_at desc")
end
def show
#products = Product.where("category_id = ?", #product.id)
#categories = Category.all
end
def new
#catgories = Category.new
end
def create
#category = Category.new(category_params)
respond_to do |format|
if #category.save(category_params)
format.html { redirect_to categories_path, notice: 'Category was successfully created.' }
format.json { render :show, status: :created, location: #category }
else
format.html {render :new, notice: "Category failed to be created" }
format.json { render json: #category.errors, status: :unprocessable_entity}
end
end
end
def electronics
end
def home
end
def update
#category = Category.new(category_params)
respond_to do |format|
if #category.update(category_params)
format.html { redirect_to categories_path, notice: 'Category was successfully updated.' }
format.json { render :show, status: :ok, location: #category }
else
format.html {render :edit, notice: "Category failed to be updated" }
format.json { render json: #category.errors, status: :unprocessable_entity}
end
end
end
def destroy
#category.destroy
respond_to do |format|
format.html { redirect_to categories_path, notice: "Category has been deleted" }
format.json { head :no_content }
end
end
private
def set_category
#category = Category.find(params[:id])
end
def category_params
params.require(:category).permit(:title)
end
end
products_controller.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
before_action :category_order, only: [:index, :show, :edit, :new]
before_action :products_order, only: [:index, :show]
before_action :authenticate_user!, except: [:index, :show]
# GET /products
# GET /products.json
def index
#products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new, notice: "Product could not be saved" }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit, notice:"Product could not be updated" }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:name, :price, :image, :category_id, :description)
end
def products_order
#products = Product.all.order("created_at desc")
end
#category
def category_order
#categories = Category.all.order("created_at desc")
end
end
If what you really want is a one-to-one association between products and categories you need to set it up properly:
class Product < ActiveRecord::Base
belongs_to :category
# ...
end
class Category < ActiveRecord::Base
has_many :products
# ...
end
Proper pluralization is really important in Rails.
Its only you want to instead have a many to many association (a product can belong to many categories) that you need a join table:
class Product < ActiveRecord::Base
has_many :product_categories
has_many :categories, through: :product_categories
# ...
end
# the join table
class ProductCategory < ActiveRecord::Base
belongs_to :product
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :product_categories
has_many :products, through: :product_categories
# ...
end

Rails generate records for secondary model on create

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

Merit doesn't add points to user after create action

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.

how do I write create method in the controller for a submission form that uses a join table?

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

Rails 4 - has_many through controller actions

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

Resources