Has And Belongs to Many Through Save and Update - ruby-on-rails

Here are my models:
class Examination < ActiveRecord::Base
has_many :categorizations
has_many :exam_statuses, :through => :categorizations
end
class Categorization < ActiveRecord::Base
belongs_to :examination
belongs_to :exam_status
end
class ExamStatus < ActiveRecord::Base
has_many :categorizations
has_many :examinations, :through => :categorizations
end
I can assign relations from the console without any problem by typing;
e = Examination.first
e.exam_status_ids = [1,2]
And also in the examinations/index.html.erb file I can list exam_statuses without any problem.
The problem is, I can't update or create any exam_status relations from examinations/_form.html.erb file!
I'm trying to make this with simple_form:
<%= f.association :exam_statuses, as: :check_boxes, label: 'Sınavın Durumu' %>
Its listing all the statuses with checkboxes but not updating them.
Logs saying:
"Unpermitted parameters: exam_status_ids"
And finally my controller, which is generated by "scaffold" by default, for update is:
def update
respond_to do |format|
if #examination.update(examination_params)
format.html { redirect_to #examination, notice: 'Examination was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #examination.errors, status: :unprocessable_entity }
end
end
end

From what your logs say, you should permit the parameter, in the controller:
def examination_params
params.require(:examination).permit(:exam_status_ids)
end
Don't forget to add other parameters in the permit call!
Then you can use it in your controller's action:
def update
...
#examination.update_attributes! examination_params
...
end

I think you need to use accepts_nested_attributes in this case to get it updated.
For more details you can refer this article

Related

rails : association tabel (has_and_belongs_to_many) not save any record

i use rails 5 , simple form. in my app there is a Category model and there is a OnlineProduct model. i dont know why when i want to add some categories to my OnlineProduct association table remain empty and don't change.
Category model:
class Category < ApplicationRecord
has_ancestry
has_and_belongs_to_many :internet_products
end
InternetProduct model:
class InternetProduct < ApplicationRecord
belongs_to :user
belongs_to :business
has_and_belongs_to_many :categories
end
InternetProduct controller:
def new
#internet_product = InternetProduct.new
end
def create
#internet_product = InternetProduct.new(internet_product_params)
respond_to do |format|
if #internet_product.save
format.html { redirect_to #internet_product, notice: 'Internet product was successfully created.' }
format.json { render :show, status: :created, location: #internet_product }
else
format.html { render :new }
format.json { render json: #internet_product.errors, status: :unprocessable_entity }
end
end
end
private:
def internet_product_params
params.require(:internet_product).permit(:name, :description, :mainpic, :terms_of_use,
:real_price, :price_discount, :percent_discount,
:start_date, :expire_date, :couponـlimitation, :slung,
:title, :meta_data, :meta_keyword, :enability, :status,
:like, :free_delivery, :garanty, :waranty, :money_back,
:user_id, :business_id,
categoriesـattributes: [:id, :title])
end
and in the view only the part of who relate to categories :
<%= f.association :categories %>
all the categories list in view (form) but when i select some of them not save in database. in rails console i do this
p = InternetProduct.find(5)
p.categories = Category.find(1,2,3)
this save to database without any problem, what should i do ?
tanks for reading this
I found solution to solve this. when we use has_and_belong_to_many or any other relation , if you want to use collection select in simple_form , in the model also should be add this command for nesting form
accepts_nested_attributes_for :categories
also in the controller in related method for example in the new we should
def new
#internet_product = InternetProduct.new
#internet_product.categories.build
end

accepts_nested_attributes causing Stack level too deep in Rails

I have a very basic example
app/models/user.rb
#name string
class User < ActiveRecord::Base
has_one :project,dependent: :destroy
validates :name,presence: true
validates_associated :project
accepts_nested_attributes_for :project
end
app/models/project.rb
#name string
#user_id integer
class Project < ActiveRecord::Base
belongs_to :user
has_many :tasks,dependent: :destroy
validates :name,presence: true
validates_associated :tasks
accepts_nested_attributes_for :tasks
end
app/models/tasks.rb
#name string
#project_id integer
class Task < ActiveRecord::Base
belongs_to :project,dependent: :destroy
validates :name,presence: true
end
That's all I have in model
On the Controller end for testing purpose, I have the following code.
app/controllers/users_controller.rb
def update
#user.project_attributes = {:name => "P#rand(100)",:tasks_attributes => [{name: "Task#{rand(100)}"}]}
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
Every time, I try to update a given User, I run into stack level too deep
problem
Any Clue?
Note :
Rails version 4.0.4
Ruby 2.1.2p95
Write dependent: :destroy only in one of models that share an association. If both models have dependent: :destroy in 'em, it goes for an infinite number of calls causing Stack level too deep error to occur.

in nested form- Can't mass-assign protected attributes:

I have read through several threads and nothing so far. I am trying to nest one form in another. I am getting the can't mass assign protected attributes error. \
app/controllers/projects_controller.rb:46:in new'
app/controllers/projects_controller.rb:46:increate'
Projects_controller.rb
def create
#project = Project.new(params[:project])
respond_to do |format|
if #project.save
format.html { redirect_to #project, notice: 'Project was successfully created.' }
format.json { render json: #project, status: :created, location: #project }
else
format.html { render action: "new" }
format.json { render json: #project.errors, status: :unprocessable_entity }
end
end
end
project.rb
WF::Application.routes.draw do
resources :line_items
resources :projects do
resources :line_items
end
devise_for :users
get 'about' => 'pages#about'
get 'Production' => 'projects#index'
root :to => 'pages#home'
end
here is the error...
ActiveModel::MassAssignmentSecurity::Error in ProjectsController#create
Can't mass-assign protected attributes: line_item
here is my project model
class Project < ActiveRecord::Base
attr_accessible :quantity
# may be unnessary
attr_accessible :line_items_attributes
belongs_to :user
has_many :line_items
accepts_nested_attributes_for :line_items, :allow_destroy => true
end
Assuming you're trying to create line items through your project model, you'll need to make sure you have the following lines in your Project model:
# project.rb
Class Project < ActiveRecord::Base
attr_accessible :line_items_attributes
accepts_nested_attributes_for :line_items
...
end
Rails is trying to protect you from accidentally assigning values you don't mean to.
You can tell Rails what values are ok to assign in this way:
attr_accessible :value1, :value2
If you add that line to the top of the Project model (replace :value1 and :value2 with the actual names of your columns), it should allow you to do what you're attempting.
For more info, here's the docs.

Rails 3.1: Validation fails when saving new objects with has_many :through association

# article.rb
class Article < ActiveRecord::Base
has_many :article_categories, dependent: :destroy
has_many :categories, through: :article_categories
validates :title, :description, :body, presence: true
validates :categories, presence: true
validates_associated :categories
end
#articles_controller.rb
def create
#article = Article.new(params[:article])
respond_to do |format|
if #article.save
format.html { redirect_to #article, notice: 'Article was successfully created.' }
format.json { render json: #article, status: :created, location: #article }
else
format.html { render action: "new" }
format.json { render json: #article.errors, status: :unprocessable_entity }
end
end
end
I have an Article model related to one or more Categories. I want to make sure that an article is assigned to a category each time the record is saved. On update, this works fine, but on create, I get an unprocessable entity because the ArticleCategory association can't be created because it needs the id of the article. But, the id isn't set until the Article is saved. But I can't save invalid models. You get the idea. How can I create objects without sacrificing my validations?
Edit: I fixed the validation line. This is cleaned up to remove some other stuff so I accidentally deleted the presence: true
Instead of validating that an article has many categories, can you try validate the presence of the join table, like:
# article.rb
validates :article_categories, presence: true
Have a look at the Rails Guides for the proper format here:
has_many :patients, :through => :appointments
From here! I think you'll find your declarations in the improper format.

Add current_user Devise to Mongoid relations

Hi Guys I have a Relationships in Mongoid and I can not add current_user to this relation for get the user that create the deal. A relation with 3 model.
I have three models user.rb, house.rb and deal.rb
user.rb Relationships (devise model)
# Relationships
has_many :houses, dependent: :destroy
has_many :deals, dependent: :destroy
key :title
house.rb
# Relationships
belongs_to :user
embeds_many :deals
deal.rb
# Relationships
embedded_in :house, :inverse_of => :deals
belongs_to :user
In my routes.rb
resources :houses do
resources :deals
end
In my houses_controller.rb in my create method I get current_user for each house of this side:
def create
##house = House.new(params[:house])
#house = current_user.houses.new(params[:house])
respond_to do |format|
if #house.save
format.html { redirect_to #house, notice: 'House was successfully created.' }
format.json { render json: #house, status: :created, location: #house }
else
format.html { render action: "new" }
format.json { render json: #house.errors, status: :unprocessable_entity }
end
end
end
In my deals_controller.rb I have the created method this:
def create
#house = House.find_by_slug(params[:house_id])
#user = User.find(:user_id)
#deal = #house.deals.create!(params[:deal])
redirect_to #house, :notice => "Comment created!"
end
How I can add to this last method create, the current_user that created the deal?
You can simply add these two lines to the create action:
#deal.user=current_user
#deal.save
And I would also suggest you not to use create! instead you should use .new and .save like in the scaffolded create actions! ;)

Resources