How to set permit_params for another model - ruby-on-rails

These are my models:
Product.rb:
class Product < ApplicationRecord
belongs_to :position
has_many :products_sizes
has_many :sizes, through: :products_sizes
has_many :reviews, dependent: :destroy
accepts_nested_attributes_for :products_sizes
end
Products_size.rb:
class ProductsSize < ApplicationRecord
belongs_to :product
belongs_to :size
has_many :prices
accepts_nested_attributes_for :prices
end
Size.rb:
class Size < ApplicationRecord
has_many :products_sizes
has_many :products, through: :products_sizes
end
and Price.rb:
class Price < ApplicationRecord
belongs_to :products_size
end
In ActiveAdmin I need to make a form for Product, for when I update the product, I could create a Price, so a part of the form looks like this:
... #here is the begining of the form
f.inputs 'Sizes' do
f.semantic_fields_for ProductsSize.where(product_id: params[:id], size_id: Product.find(params[:id]).products_sizes.size.to_i).first.prices.new do |ps|
ps.input :products_size_id, label: 'Size', as: :select, collection: Product.find(params[:id]).sizes.map { |s| ["#{s.title}", s.id] }
ps.input :quantity
ps.input :amount
li do
link_to 'Add size', '#'
end
end
end
It's all seems to be good, except when clicking the submit button, the Price isn't created. I think, that's because the permit_params are not specified for price. How can I specify them? Thanks.

ActiveAdmin.register Post do
permit_params :title,
comments_attributes: [:name, :hidden]
end
Post is a moodel and comments is another. You can use params from comments with comments_attributes, if your model name is price you can use price_attributes: [...params...].

Here is how you allow parameters in active admin
ActiveAdmin.register Post do
permit_params :title, :content, :author
end
This is just an example, use your own params

Related

Rails: Structuring rental orders & order form in ecommerce-like setting

I was wondering if someone could help me out with an application that has some ecommerce characteristics.
Context: Via the application a bike shop chain ('chains') can rent out
bikes ('bikes'),
by picking out a bike type such as mountainbike, city bike etc. ('bike_types) and
bike options, such as helmets etc. ('bike_options')
which are dependent on the individual bike store ('bike_stores')
this rental of the bikes & options will all be captured in an order ('orders')
the relationship between orders and bikes is many-to-many, therefore I created a table to bridge this ('order_bikes')
Final notes:
Before the rental process, the chain owner first created his/her (i) bike_stores, (ii) bike_types, (iii) bikes and (iv) bike_options, this part of the application is working. Therefore, he/she only needs to select bike_types/bikes/options out of the existing inventory previously created.
I limit the scope of the question by leaving out the bike_options, this was mainly to provide some context in order to understand the db schema build up.
Error message: Unpermitted parameter: :bike_id
Code:
models
class Order < ApplicationRecord
belongs_to :bike_store
has_many :bike_types, through: :bike_store
has_many :order_bikes, inverse_of: :order, dependent: :destroy
accepts_nested_attributes_for :order_bikes, allow_destroy: true
end
class OrderBike < ApplicationRecord
belongs_to :bike
belongs_to :order
accepts_nested_attributes_for :bike
end
class Bike < ApplicationRecord
belongs_to :bike_type
validates :name, presence: true
has_many :order_bikes
has_many :orders, through: :order_bikes
end
class BikeType < ApplicationRecord
belongs_to :bike_store
has_many :bikes, dependent: :destroy
accepts_nested_attributes_for :bikes, allow_destroy: true
has_many :bike_options, dependent: :destroy
accepts_nested_attributes_for :bike_options, allow_destroy: true
validates :name, :bike_count, presence: true
end
class BikeStore < ApplicationRecord
has_many :bike_types, dependent: :destroy
has_many :orders, dependent: :destroy
end
Order controller
class OrdersController < ApplicationController
def new
#bike_store = BikeStore.find(params[:bike_store_id])
#order = Order.new
#order.order_bikes.build
#bike_type_list = #bike_store.bike_types
end
def create
#order = Order.new(order_params)
#bike_store = BikeStore.find(params[:bike_store_id])
#order.bike_store = #bike_store
#order.save
redirect_to root_path
end
private
def order_params
params.require(:order).permit(:arrival, :departure,
order_bikes_attributes: [:id, :bike_quantity, :_destroy,
bikes_attributes: [:id, :name,
bike_types_attributes: [:id, :name]]])
end
end
view
<%= simple_form_for [#bike_store, #order] do |f|%>
<%= f.simple_fields_for :order_bikes do |order_bike| %>
<%= order_bike.input :bike_quantity %>
<%= order_bike.association :bike %>
<% end %>
<%= f.input :arrival %>
<%= f.input :departure %>
<%= f.submit %>
<% end %>
If you check coed from simple form here, you will see what actually method association does.
def association(association, options = {}, &block)
# ... simple form code here ...
attribute = build_association_attribute(reflection, association, options)
input(attribute, options.merge(reflection: reflection))
end
We are interested in build_association_attribute method call. here
def build_association_attribute(reflection, association, options)
case reflection.macro
when :belongs_to
(reflection.respond_to?(:options) && reflection.options[:foreign_key]) || :"#{reflection.name}_id"
# ... the rest of code ...
end
end
Your order bike model has belongs_to :bike association. So when you call order_bike.association :bike it builds :bike_id attribute in your form. If you check params hash that comes to your controller, I believe you'll see that attribute coming from your view.
I added bike_id to permitted parameters. I hope it will fix your problem..
def order_params
params.require(:order).permit(:arrival, :departure,
order_bikes_attributes: [:id, :bike_id, :bike_quantity, :_destroy,
bikes_attributes: [:id, :name,
bike_types_attributes: [:id, :name]]])
end

How do I access the extra attribute on join table in my show page?

My models look like this:
class Project < ApplicationRecord
has_many :comments
has_many :contractor_projects
has_many :contractors, through: :contractor_projects
validates_presence_of :title, :contract_number, :category, :project_start_date, :project_end_date, :substantial_completion_date, :category, :solicitation_number, :project_officer, :location
accepts_nested_attributes_for :contractor_projects
end
class Contractor < ApplicationRecord
has_many :contractor_projects
has_many :projects, through: :contractor_projects
validates :name, presence: true
validates :email, presence: true, uniqueness: true
end
class ContractorProject < ApplicationRecord
belongs_to :contractor
belongs_to :project
end
The ContractorProject model has an extra attribute #bid_status that I want to reflect on project's show page but it does not appear even though it's in the params when i raised it.
below is sample method for your case
def show
#project = Project.find(params[:id]
#contractors = #project.contractors
end
inside show.html.erb, you have to loop it, since it may get more than one records
<% #contractors.each do |contractor| %>
<%= contractor.bid_status %>
<% end %>

Rails 4 strong parameters does not work for a polymorphic association

I have set a polymorphic association and added a nested form in the view. Im trying to create the main record and the association at the same time. The main record gets created but the association won't.
Here are the two models in question :
class UnRegistered < ActiveRecord::Base
has_one :vehicle, as: :detailable, dependent: :destroy
belongs_to :dealer
class Vehicle < ActiveRecord::Base
belongs_to :purchase_details, polymorphic: true
belongs_to :brand
belongs_to :model
belongs_to :color
belongs_to :customer
Here's the form definitions :
<%= form_for(#un_registered, url: panel_un_registereds_path, remote: true) do |f| %>
<%= f.fields_for :vehicle do |f_vehicle| %>
Here's a sample params set I get :
{"utf8"=>"✓", "un_registered"=>{"vehicle"=>{"brand_id"=>"", "model_id"=>"", "year"=>"", "engine_number"=>"gdfg", "chassis_number"=>"", "color"=>"", "options"=>""}, "original_price"=>"", "insurance"=>"", "freight"=>"", "tt"=>"", "tt_date"=>"", "duty"=>"", "clearance_fee"=>"", "other_expenses"=>"", "dealer_id"=>"", "landing_date"=>"", "loading_date"=>""}, "controller"=>"panel/un_registereds", "action"=>"create"}
Here's the controller actions :
def create
#un_registered = UnRegistered.create(un_registered_params)
end
def un_registered_params
params.require(:un_registered).permit(:original_price, :insurance, :freight, :tt, :tt_date, :duty, :clearance_fee, :other_expenses, :loading_date, :landing_date, :dealer_id, vehicle_attributes: [:id, :brand_id, :model_id, :engine_number, :chassis_number, :color_id, :year, :options, :selling_price, :customer_id, :purchase_date, :_destroy])
end
Full form code :
https://gist.github.com/THPubs/9665e0e5594e15fcc76a
New method :
def new
#un_registered = UnRegistered.new
end
Your form is fine. You just need to add below changes.
In your un_registered.rb model
class UnRegistered < ActiveRecord::Base
has_one :vehicle, as: :detailable, dependent: :destroy
belongs_to :dealer
accepts_nested_attributes_for :vehicle #this one
end
And in your controller,
def new
#un_registered = UnRegistered.new
#un_registered.build_vehicle #this one
end

Formtastic Has Many Through Association

I have a Campaign model and a Category model. They have a has-many-through relationship with each other. The intermediate model is campaign_categories.
Campaign:
class Campaign < ActiveRecord::Base
attr_accessible :name, :carousel_image, :show_in_carousel, :title, :carousel_description,
:video_embed_code, :goal, :end_date, :backer_count, :author_name, :author_photo,
:author_description_md, :author_description_html, :description_markdown, :description_html,
:funds_description_md, :funds_description_html, :campaign_status_id
#associations
has_many :campaign_categories
has_many :categories, through: :campaign_categories
end
Category:
class Category < ActiveRecord::Base
attr_accessible :name
#associations
has_many :campaign_categories
has_many :campaigns, through: :campaign_categories
end
Campaign_Category:
class CampaignCategory < ActiveRecord::Base
attr_accessible :campaign_id, :category_id
belongs_to :campaign
belongs_to :category
end
I have following in campaigns.rb for Activeadmin:
ActiveAdmin.register Campaign do
form :html => { :enctype => 'multipart/form-data'} do |f|
f.inputs "Campaign Basic Information" do
f.input :name
f.input :categories
end
f.actions
end
end
The categories show up correctly in a multi select box. But I receive following error on form submission:
Can't mass-assign protected attributes: category_ids
I tried calling accepts_nested_attributes_for :categories in Campaign, but that did not work. How can I resolve this issue? Thanks.
Adding :category_ids to your attr_accessible call in the Campaign model should do it

Searching one model by another

My application consists of a drink model
class Drink < ActiveRecord::Base
attr_accessible :name
has_many :recipe_steps, :dependent => :destroy
has_many :ingredients, through: :recipe_steps
end
An ingredient model
class Ingredient < ActiveRecord::Base
attr_accessible :name
has_many :recipe_steps
end
how would I go about having it so when a user searches an ingredient that it returns all of the drinks with that ingredient?
Additional information: I'm currently using sunspot/solr for my searching.
First, in your Ingredient model you'd need this line:
has_many :drinks, through: :recipe_steps
To define the has_many, through: relationship. Make sure that RecipeStep has these lines, too:
belongs_to :ingredient
belongs_to :drink
Then you can do something like in the DrinksController:
def search
term = params[:search]
ingredient = Ingredient.where(:name => term)
#drinks = Ingredient.find(ingredient).drinks
end
And your form should look something like this:
<%= form_for #drink, :url => { :action => "search" } do |f| %>
<%= f.text_field :search %>
<% end %>
I don't know all your names for everything but this should get you going.
Following should work fine:
class Ingredient < ActiveRecord::Base
...
has_many :recipe_steps
has_many :drinks, through: :recipe_steps
end

Resources