Mongoid _destroy is not deleted embedded document using nested_form gem - ruby-on-rails-3.1

I am on Rails 3.1, Mongoid 2.3.3, and using the nested_form gem. In my form, I have the nested_form link_to_add and link_to_remove set up to add and remove an embedded document in my model. The link_to_add helper method works great, but the link_to_remove help method changes are not persisted in MongoDB. In the rails output, I can see the JSON parameter passed to Mongoid has the _destroy: 1 value set but the change is not saved to MongoDB.
Here is the Model:
class MenuItem
include Mongoid::Document
include Mongoid::Timestamps
field :name
attr_accessible :name
embeds_many :ingredient_infos
accepts_nested_attributes_for :ingredient_infos, :allow_destory => true
attr_accessible :ingredient_infos_attributes
end
Here is the Controller's update method:
def update
#menu_item = MenuItem.find(params[:id])
respond_to do |format|
if #menu_item.update_attributes(params[:menu_item])
format.html { redirect_to #menu_item, notice: 'Menu item was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: #menu_item.errors, status: :unprocessable_entity }
end
end
end
Here is the parameters sent to the controller:
{
"utf8"=>"✓",
"authenticity_token"=>"5abAWfFCr7hkzYXBEss75qlq8DMQ0pW5ltGmrgHwPjQ=",
"menu_item"=>
{
"name"=>"Bowl",
"ingredient_infos_attributes"=>
{
"0"=>
{
"ingredient"=>"Rice",
"_destroy"=>"false",
"id"=>"4eb1b0b118d72f1a26000022"
},
"1"=>
{
"ingredient"=>"Chicken",
"_destroy"=>"1",
"id"=>"4eb1b0b118d72f1a26000025"
}
}
},
"commit"=>"Update Menu item",
"id"=>"4eb1b0b118d72f1a2600001f"
}
In MongoDB, the Chicken document still exists; that document also shows up in the view online (the page pulls all the items in the embedded document).
I'm sure I missed something, but I haven't been able to figure out why the embedded document isn't removed.

yes, your :allow_destory should be :allow_destroy

I am experiencing the same issue -
RESOLVED with
accepts_nested_attributes_for :phones, :allow_destroy => true

Related

ActiveModel serializer ignores root key when posts or post is empty or nil

I am using active model serializer V0.10.0 with Rails 5 api only application. During implementation I noticed the AMS is completely ignoring the root key when the posts/post is empty or nil respectively. This behavior actually breaks my mobile app as it always expects root key data in all response.
So what I want to achieve here is no matter what I always want data as root element of my Rails app response for all requests.
Response for SHOW API when the post is empty
SHOW render json: #post, root: 'data'
Expected
{
"data": {}
}
Actual
null
Response for INDEX API when the posts are empty
INDEX render json: #posts, root: 'data'
Expected
{
"data": []
}
Actual
{
"posts": []
}
class ApplicationSerializer < ActiveModel::Serializer
include Rails.application.routes.url_helpers
ActiveModelSerializers.config.adapter = :json
def host
Rails.application.secrets.dig(:host_url)
end
end
class PostSerializer < ApplicationSerializer
attributes :id
has_many :comments
end

Include and group JSON by parent model

I am currently calling an API to get a publisher's Books. I am then grouping each book into different their respective story Arcs. Everything works great and I am able to retrieve the JSON in my app.
But, I'd like to change my current JSON response and remove the JSON root arcs:
Does anyone know how I can remove the JSON root and specify which book attributes I want?
Also, would a :has many => through association help simplify this and group things how i want?
This is my code.
Models
class Publisher < ActiveRecord::Base
has_many :books
end
class Arc < ActiveRecord::Base
has_many :books
end
class Book < ActiveRecord::Base
belongs_to :arc
belongs_to :book
end
Current Json
{
"arcs": [
{
"books": [
{
"arc_id": 1,
"created_at":"2014-12-27T20:54:46.518Z",
"id": 311,
"publisher_id": 7,
"updated_at":"2015-06-04T20:55:28.190Z"
}
],
"id": 1,
"name": "One-Shot"
}
]
}
How can I change it to this?
[
{
"books": [
{
"arc_id": 1,
"id": 311,
"publisher_id": 7
}
],
"id": 1,
"name": "One-Shot"
}
]
Controller
def index
#publisher = Publisher.find(params[:publisher_id])
#books = #publisher.books.order("positioning")
#results = {arcs: []}
#books.group_by(&:arc).each do |arc, books|
#results[:arcs] << {
id: arc.id,
name: arc.name,
books: books
}
end
respond_to do |format|
format.html
format.json { render :json => #results.to_json }
end
end
I have also tried using rabl in the link below, but it's not working..
https://stackoverflow.com/questions/30660136/include-group-by-parent-model-json-rabl
you could just render back without the arcs e.g.
format.json { render :json => #results[:arcs].to_json }
That being said you could also just change the controller method as well to this but you will have to change how the html response handles #results:
def index
#publisher = Publisher.find(params[:publisher_id])
#books = #publisher.books.order("positioning")
#results = #books.group_by(&:arc).map do |arc, books|
{
id: arc.id,
name: arc.name,
books: books
}
end
respond_to do |format|
format.html
format.json { render :json => #results.to_json }
end
end
This will also give you the desired result because map in this case will just return an Array of the Hashes you have designed.

Rails 4 ActiveModel::MissingAttributeError in OrdersController#create

I m trying to build a shopping cart for a website. I have the cart working so you can add to the cart. The problem I am having is when I try and checkout items in the cart and try to submit my order. I am getting the following error:
ActiveModel::MissingAttributeError in OrdersController#create
along with
can't write unknown attribute `order_id'
The problem is highlighting this piece of code in my orders_controller.rb file
respond_to do |format|
if #order.save
Cart.destroy(session[:cart_id]) session[:cart_id] = nil
I just cant seem to fix this error.
Below is the create method in my orders_controller.rb file
def create
#order = Order.new(order_params)
#order.add_line_items_from_cart(#cart)
respond_to do |format|
if #order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
format.html { redirect_to store_url,
notice: 'Thank you for your order.' }
format.json { render action: 'show', status: :created, location: #order }
else
format.html { render action: 'new' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
my migration file
class AddOrderToLineItem < ActiveRecord::Migration
def change
add_column :line_items, :order, :reference
end
end
my order.rb model
class Order < ActiveRecord::Base
has_many :line_items, dependent: :destroy
validates :name, :address, :email, presence: true
PAYMENT_TYPES = [ "Check", "Credit card", "Purchase order" ]
validates :pay_type, inclusion: PAYMENT_TYPES
def add_line_items_from_cart(cart)
cart.line_items.each do |item|
item.cart_id = nil
line_items << item
end
end
end
migration order table
class CreateOrders < ActiveRecord::Migration
def change
create_table :orders do |t|
t.string :name
t.text :address
t.string :email
t.string :pay_type
t.timestamps
end
end
end
Ok, I think I see the problem. Your migration for orders in line items probably didn't create the order_id column you expected, it probably created an orders column or something.
Verify that this is the case in the database. If so, undo your previous migration and try this instead:
class AddOrderToLineItem < ActiveRecord::Migration
def change
add_column :line_items, :order_id, :int
end
end
If not, please respond to this answer.

how to use sunspot_mongo

In my application i have created a model under mongoDB, then i reindexed it to solr using sunspot_mongo. I want to search from solr,
My model is,
`require 'sunspot_mongo'
class Post
include Mongoid::Document
include Sunspot::Mongo
field :title
field :content
field :author, type: String
searchable do
text :title, :stored => true
text :content
end
end`
and my controller index method is,
def index
##posts = Post.all
search=Post.search do
fulltext 'hello'
end
#posts = search.results
respond_to do |format|
format.html # index.html.erb
format.json { render json: #posts }
end
end
but it showing error as,
uninitialized constant Sunspot::Mongo::DataAccessor::BSON
i couldn't fix this error
i used this in gem file
gem "sunspot_mongo", :git => "git://github.com/balexand/sunspot_mongo.git", :branch => "fix_rake_sunspot_reindex"
your model looks fine
change your controller code as below
def index
search=Post.solr_search do
fulltext params[:search]
end
#posts = search.results
respond_to do |format|
format.html # index.html.erb
format.json { render json: #posts }
end
end

Nested Attributes for Mongoid has_one relationship

I am trying to create a contact which is a has_one relation to a client. I am doing this with nested attributes. I am properly building the contact within the "new" view/controller. When I go to save the contact it is telling me the contact must be present. So for some reason it is not creating the contact.
ERROR:
Validation failed - Contact can't be blank.
Params:
{
"utf8"=>"✓",
"authenticity_token"=>"ep6es356WY5dja7D7C5Kj8Qc0Yvuh3IN2Z1iGG08J7c=",
"client"=>{
"contact_attributes"=>{
"first_name"=>"Scott",
"last_name"=>"Baute"
},
"commit"=>"Create Client"
}
Models:
class Client
include Mongoid::Document
include Mongoid::Timestamps
attr_accessible :role, :contact_id, :contact_attributes
# Relationships
belongs_to :firm, validate: true
has_one :contact, validate: true, autosave: true
# Matters is custom relationship
has_many :client_roles
# Nested Attr
accepts_nested_attributes_for :contact
validates :contact_id, presence: true
# Fields
field :contact_id
field :test
end
class Contact
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::MultiParameterAttributes
#Relationships
belongs_to :client
field :first_name
field :last_name
end
Controller:
# GET /clients/new
# GET /clients/new.json
def new
#client = current_firm.clients.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #client }
end
end
# POST /clients
# POST /clients.json
def create
#client = current_firm.clients.new(params[:client])
respond_to do |format|
if #client.save!
format.html { redirect_to client_path(#client.contact.id), notice: 'Client was successfully created.' }
format.json { render json: #client, status: :created, location: #client }
else
format.html { render action: "new" }
format.json { render json: #client.errors, status: :unprocessable_entity }
end
end
end
View:
- #client.build_contact unless #client_contact
= semantic_form_for #client, html: { class: "form-horizontal"} do |f|
.control-group
= render "contact_fields", f: builder
.form-actions
= f.submit class: "btn btn-primary"
I think you need delete your reference to contact_id in your Client model. The has_one association do the foreign_key in your contact. Not in your client. So when you create a contact from client, only a client_id is define in your contact no contact_id in your client.
So delete line :
validates :contact_id, presence: true
# Fields
field :contact_id
in your Client model.

Resources