undefined method `model_name' for ActiveModel::Errors:Class - ruby-on-rails

I have the following mongoid model class:
class Exercise
include Mongoid::Document
field :name, :type => String
field :description, :type => String
belongs_to :group
validates_presence_of :name, :description, :group
end
And I have the following controller:
class ExercisesController < ApplicationController
respond_to :json
def create
#exercise = Exercise.create(params[:exercise])
if #exercise.save
respond_with #exercise
else
respond_with(#exercise.errors, :status => :unprocessable_entity)
end
end
end
The model saves fine when valid but when the following line is ran:
respond_with(#exercise.errors, :status => :unprocessable_entity)
I get the following error
undefined method `model_name' for ActiveModel::Errors:Class
The errors collection is populated so I think my respond_with syntax is wrong.

The rails respond_with helper expects to receive a rails model objects as the 1st parameter. So in this case you'd just want respond_with #exercise, status: :unprocessable_entity And then in your response view you would need to properly format the error data, I'm assuming you are doing this via ajax and responding with json, etc. Hope that helps.

Related

ActiveModel Serializer not working for function

I am using ActiveModelSerialziers in my Rails API and it works like a charm but 1 of my functions seems to override it, and only returns my model (without any of the associations). The same model returns properly if a different function is called.
def getClient
type = params[:type]
if type == 'user'
#client = Client.find_by(user_id: params[:id])
else
#client = Client.find_by(id: params[:id])
end
render json: { success: true, response: #client }
end
only returns the client without the associations and the serializer is:
class API::ClientSerializer < ActiveModel::Serializer
attributes :name, :age, :address
belongs_to :user
has_many :check_ins
has_many :client_docs
has_many :payments
end
While the same model (Client) returns properly (with associations) when the following function is called:
def show
model_name = params[:model].classify
item = model_name.constantize.find_by(id: params[:id])
render json: item, status: :ok
end
Why might this happen?
You are missing adapter: :json from the rander statement:
render json: item, adapter: :json, status: :ok

Mixing GlobalID::Identification for form object

Rails 4.2.5
I have Form object Feedback.
class Feedback
include ActiveModel::Model
attr_accessor :name, :message
validates :name, :message, presence: true
end
And controller FeedbacksController
def create
#feedback = Feedback.new(feedback_params)
if #feedback.valid?
FeedbackServiceMailer.new_feedback(#feedback).deliver_later
redirect_to root_url, notice: 'Thanks for your feedback!'
else
render :index, status: 400
end
end
To be able to pass #feedback object to Mailer. I have added GlobalID::Identification mixin and provided id and self.find methods:
def id
object_id
end
def self.find(id)
ObjectSpace._id2ref(id.to_i)
end
My question, is it okay to provide object_id for deserializing Form object?
As I understood Ruby GC will not collect #feedback object if something have a reference to it.

render multiple queries as json in rails controller

I have two rails controller actions:
def show
#project = Project.find(params[:id])
render json: #project,
:only => [:id, :compilation_id],
:methods => :track_name,
:include => {
:user => { :only => [:id, :email] }
}
end
def list_users
render json: User.select(:id, :email)
end
I would like to render them both in one response. What is the best way to go about doing this? I tried using the to_json method as described here but I read that that method is deprecated and I also noticed that it escapes the content which seems to be unnecessary. Any help is appreciated.
For the cases where you need json structures complicated enough for to_json to look readable, I recommend to use active_model_serializers gem.
You can then define two serializer classes like this:
class ProjectSerializer < ActiveModel::Serializer
attributes :id, :compilation_id
has_many :users
end
class UserSerializer < ActiveModel::Serializer
attributes :id, :email
end
And then in your controller:
class ProjectsController < ApplicationController
def show
#project = Project.find(params[:id])
render json: #project, serializer: ProjectSerializer, status: 200
end
end
As a bonus track, you can even cache the response!
The solution, of course, was pretty simple:
project = Project.select(:id, :compilation_id, :user_id, :genre_id, :ordering).find(params[:id])
render json: { :project => project,
:users => User.select(:id, :email),
:genres => Genre.select(:id, :name),
:track_name => project.track_name
}

Rails Paperclip Attachment not saving because polymorphic id not assigned

I am brand new here. I have been fighting with a rails app for hours now and need an answer. I have searched and tried many suggestions related to what I am trying to accomplish, but to no avail. I got the paperclip gem running for my rails app yesterday, and it was a breeze to add an attachment to a single model. However, I defined an agnostic, polymorphic attachments table to hold attached files for all models that need this functionality.
My issue is that I cannot get the attached file to save through nested parameters. All my parameters are accepted, but the db rolls back and doesn't save (using guard). Message is: 'attachments.attachable_id'=>'can't be blank'. I need this to be the foreign key of the related table, and this has to be saved along with the attachment_type. Here's what I have:
class ReportsController < ApplicationController
def new
#report = Report.new
#report.attachments.build(attachable_id: #report.id)
end
def create
#report = Report.new(params)
#report.attachments.build
respond_to do |format|
if #report.save
format.html { redirect_to #report, notice: 'Report was successfully created.' }
format.json { render json: #report, status: :created, location: #report }
else
format.html { render action: "new" }
format.json { render json: #report.errors, status: :unprocessable_entity }
end
end
end
private
def report_params
params.require(:report).permit(:filing_year, :filing_number, :order_number, :location, :environmental_review,:biological_review, :cultural_review, :date_received, :status, attachments_attributes: [:id, :attachable_id, :attachable_type, :attachment])
end
end
And for the models:
class Attachment < ActiveRecord::Base
belongs_to :attachable, polymorphic: true
validates :attachable_id, :attachable_type, presence: true
do_not_validate_attachment_file_type :attachment
Paperclip.interpolates :attached_to do |attachment, style|
attachment.instance.attachable.class.to_s.downcase
end
has_attached_file :attachment,
:url => "/attachments/:id/:basename.:extension",
:path => ":rails_root/public/attachments/:attached_to/:id/:basename.:extension",
:default_url => "/attachments/original/no-file.txt"
end
class Report < ActiveRecord::Base
has_one :environmental_review
has_many :attachments, as: :attachable
accepts_nested_attributes_for :attachments
validates :order_number, presence: true
.
.
.
end
And view (in slim):
.report
= form_for #report do |f|
.
.
.
= f.fields_for :attachments do |a|
= a.file_field :attachment
.
.
.
Thank you.
Well for one in your create method you call #reports.attachments.build again, but don't set the assignable_id, you need to do that. The other thing you can do is add a hidden form field that has the name attachable_id.

Rails many to many token fields help

I am having that problem that my model dont want to save. I have a token field input for tags.
I have followed this guide for the token input: http://railscasts.com/episodes/258-token-fields
I get this error when I try to create a new konkurrancer:
NoMethodError in Admin/konkurrancersController#create
undefined method `class_name' for nil:NilClass
Rails.root: C:/Rails/konkurranceportalen
Application Trace | Framework Trace | Full Trace
app/models/konkurrancer.rb:15:in `tag_tokens='
app/controllers/admin/konkurrancers_controller.rb:48:in `new'
app/controllers/admin/konkurrancers_controller.rb:48:in `create'
http://pastie.org/1834194
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"yo7wcAQl81tx3zZpPP44ENPYzYRZLpgyYKY+HK3yFKM=",
"konkurrancer"=>{"name"=>"Vind en rejse",
"banner2"=>"asdasd",
"tracking"=>"sadasd",
"vaerdi"=>"12222",
"tid"=>"1 min",
"tag_tokens"=>"1",
"bedom"=>"2",
"kategori_id"=>"9",
"form"=>"Nyhedsbrev",
"partner"=>"Iqmedier",
"udtraekkes(3i)"=>"30",
"udtraekkes(2i)"=>"4",
"udtraekkes(1i)"=>"2011",
"udtraekkes(4i)"=>"08",
"udtraekkes(5i)"=>"26",
"arrangeor"=>"",
"note"=>""},
"commit"=>"Opret konkurrence"}
My konkurrancer model:
class Konkurrancer < ActiveRecord::Base
attr_accessible :name, :tag_tokens
has_many :tagsmenus
has_many :tags, :through => :tagsmenus
attr_reader :tag_tokens
def tag_tokens=(ids)
self.tag_ids = ids.split(",")
end
end
My tag model:
class Tag < ActiveRecord::Base
has_many :tagsmenus
has_many :konkurrancers, :through => :tagsmenus
has_friendly_id :name, :use_slug => true
before_save :assign_cached_slug, :unless => :cached_slug?
protected
def assign_cached_slug
self.cached_slug = self.name.gsub(/\s+/, '_').gsub(/[^\w\-]/, '')
end
end
My tagmenu model:
class Tagsmenu < ActiveRecord::Base
end
My controller:
def new
#konkurrancer = Konkurrancer.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #konkurrancer }
end
end
# POST /konkurrancers
# POST /konkurrancers.xml
def create
#konkurrancer = Konkurrancer.new(params[:konkurrancer])
respond_to do |format|
if #konkurrancer.save
format.html { redirect_to(:admin_konkurrancers, :notice => 'Konkurrancer was successfully created.') }
format.xml { render :xml => :admin_konkurrancers, :status => :created, :location => #konkurrancer }
else
format.html { render :action => "new" }
format.xml { render :xml => #konkurrancer.errors, :status => :unprocessable_entity }
end
end
end
I have created the join table and the model and also added the relation to my tag model.
Your model has some conflicting statements. You first define:
attr_accessor ... :tag_tokens
then later have:
attr_reader :tag_tokens
which is not necessary given the first line or vice versa given that later you have a deinition for the setter:
def tag_tokens(ids)
self.tag_ids = ids.split(',')
end
I don't see tag_ids defined either given it is not a column in your table. You should probably remove the attr_accessor definition for the tag_tokens and then define the tag_ids method for starters.
class Tagsmenu < ActiveRecord::Base
belongs_to :konkurrancer
belongs_to :tag
end

Resources