Rails 3, :json => #model.to_json OR :json => #model - ruby-on-rails-3

I just wandered the difference between:
format.json { render :json => #post, :include => [ :user ] }
...and
format.json { render :json => #post.to_json(:include => [ :user ]) }
They both seem to work?

it's the same. if you have a look at actionpack renderers.rb you will see how it works:
add :json do |json, options|
json = json.to_json(options) unless json.kind_of?(String)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
self.content_type ||= Mime::JSON
json
end

Related

Accepts_nested_attributes_for child validation not working

I have a model called Test that accepts_nested_attributes_for SubTest. A Test basically has an id, and there are multiple SubTests associated with an individual Test.
I want to validate that an attribute of the SubTest is numeric. Here are my models so far.
class Test < ActiveRecord::Base
has_many :sub_tests
accepts_nested_attributes_for :sub_tests
end
class SubTest < ActiveRecord::Base
belongs_to :test
validates :measurement, :numericality => true, :allow_nil => true
end
Here is the Test controller
def create
respond_to do |format|
if #test.save
flash.now[:notice] = "Test Created"
format.html { redirect_to(#test) }
format.xml { render :xml => #test, :status => :created, :location => #test }
format.js
else
flash.now[:error] = "[Error] Test Not Created Because: #{#test.errors.full_messages.join(", ")}"
format.html { render :action => "new" }
format.xml { render :xml => #test.errors, :status => :unprocessable_entity }
format.js
end
end
end
I want the create action in the controller to throw an error if the user enters a non-numeric string in the form for the sub_test.
Currently, if I enter non-numeric values for a sub_test.measurement, Rails doesn't create the Test or SubTest objects (desired behavior). But for some reason no error is thrown, and the Test controller triggers the create.js.erb partial.
I'm getting the impression that the validation for the numericality of sub_test.measurement should actually happen in the Test model, but I'm not sure how to write a custom validation method that tests for numericality.
Thanks in advance!
Got it. I needed to specify an _error.js.erb partial in my Test controller.
def create
respond_to do |format|
if #test.save
flash.now[:notice] = "Test Created"
format.html { redirect_to(#test) }
format.xml { render :xml => #test, :status => :created, :location => #test }
format.js
else
flash.now[:error] = "[Error] Test Not Created Because: #{#test.errors.full_messages.join(", ")}"
format.html { render :action => "new" }
format.xml { render :xml => #test.errors, :status => :unprocessable_entity }
format.js { render :partial => 'error' }
end
end
In the error partial I just appended my #messages div (since I'm doing form submissions through ajax.)

undefined method for nil:NilClass

upload controller
def create
#upload = #order.uploads.build(params[:uploadtwo])
respond_to do |format|
if #upload.save
format.html { redirect_to root_path, :notice => 'File was successfully uploaded.' }
format.json { render :json => #upload, :status => :created, :location => #upload }
else
format.html { render :action => "new" }
format.json { render :json => #upload.errors, :status => :unprocessable_entity }
end
end
upload model
belongs_to :order
order model
has_many :uploads
i get error [NoMethodError in UploadtwosController#create ], [undefined method `uploads' for nil:NilClass]
anybody knows what am not doing?
Just declaring belongs_to :order in your Upload model does not mean that #order will automatically be defined in the controller. Perhaps what you want is a before_filter in the controller which will set #order?

Rails 3: Return JSON with a specific variable

I have a method returning this:
format.json { render :json => #call, :include => :customer }
However, I want the #call.created_at to return as a more readable datetime.
How can I do that?
thanks
You can create a method in your model to prettify the time.
class Call < ActiveRecord::Base
def formatted_time
#Pretty time
end
end
format.json { render :json => #call, :include => :customer, :methods => :formatted_time }

Devise and Authentication with CURL !

I would like to be able to authenticate through a curl style !
So I would like to get a Token when I signed in :
curl -X POST 'http://localhost:3000/users/sign_in.json' -d 'user[email]=em...#provider.us&user[password]=pass'
But if I perform this action I only get :
{"email":"em...#provider.us","name":"Name of the user"}
How I could add some specific fields like authentication_token ?
Is what I want to do is right ? Is there any other better way to do
this ?
Thanks !
I created a Controller named SessionController
class Users::SessionsController < Devise::SessionsController
append_view_path 'app/views/devise'
def create
respond_to do |format|
format.html { super }
format.json {
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
current_user.ensure_authentication_token!
render :json => {:user => current_user.api_attributes, :auth_token => current_user.authentication_token}.to_json, :status => :ok
}
end
end
def destroy
respond_to do |format|
format.html { super }
format.json {
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
current_user.empty_authentication_token!
render :json => {}.to_json, :status => :ok
}
end
end
end
And added this to the root file :
devise_for :users, :controllers => { :sessions => "users/sessions" }
And it works :-)

Rails 3 - Atom Feed Help Needed?

Am having trouble getting the Atom feed function to work on my blog. I am using the Kaminari plug-in to paginate my articles - 6 per page. With the code below, when a user clicks on the RSS Feed image they are asked to log-in instead of subscribing to the feed! Any help would be appreciated with this issue...
application.html.erb
page head <%= auto_discovery_link_tag(:atom, feed_path, { :title => "My ATOM Feed" }) %>
page body <%= image_tag("feed.png", {:alt => 'Atom feed', :class=>"feed"}) %>Subscribe
routes.rb
match '/feed' => 'articles#feed', :as => :feed, :defaults => { :format => 'atom' }
articles_controller
class ArticlesController < ApplicationController
before_filter :authenticate_user!, :except => [:index, :show]
# GET /articles
# GET /articles.xml
# display articles on the home page
def index
#articles = Article.published.page(params[:page]).per(6).ordered
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #articles }
format.atom { render :atom => #articles }
end
end
# GET /articles/1
# GET /articles/1.xml
def show
#article = Article.find(params[:id])
#comment = Comment.new(:article=>#article)
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #article }
end
end
# GET /articles/new
# GET /articles/new.xml
def new
#article = Article.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #article }
end
end
# GET /articles/1/edit
def edit
#article = Article.find(params[:id])
authorize! :edit, #article
end
# POST /articles
# POST /articles.xml
def create
#authorize! :create, #article
#article = Article.new(params[:article])
#article.user_id = current_user.id
respond_to do |format|
if #article.save
format.html { redirect_to(#article, :notice => 'Worry was successfully created.') }
format.xml { render :xml => #article, :status => :created, :location => #article }
else
format.html { render :action => "new" }
format.xml { render :xml => #article.errors, :status => :unprocessable_entity }
end
end
end
# PUT /articles/1
# PUT /articles/1.xml
def update
#article = Article.find(params[:id])
authorize! :update, #article
respond_to do |format|
if #article.update_attributes(params[:article])
format.html { redirect_to(#article, :notice => 'Worry was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #article.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /articles/1
# DELETE /articles/1.xml
def destroy
#article = Article.find(params[:id])
authorize! :destroy, #article
#article.destroy
respond_to do |format|
format.html { redirect_to(articles_url) }
format.xml { head :ok }
end
end
end
views/articles/feed.atom.builder
atom_feed :language => 'en-US' do |feed|
feed.title "mysite.com"
feed.updated(#articles.blank? ? Time.now : #articles.first.created_at)
#articles.each do |article|
feed.entry article, :published => article.accepted do |entry|
entry.title article.title
entry.author do |author|
author.name article.user.fullname
end
end
end
end
Update this line in your articles_controller:
before_filter :authenticate_user!, :except => [:index, :show]
... with:
before_filter :authenticate_user!, :except => [:index, :show, :feed]
This will prevent the request for authentication.
Two suggestions:
1) Add :url and :root_url to the atom_feed call.
2) Change:
feed.updated #articles.first.created_at
to:
feed.updated(#articles.blank? ? Time.now : #articles.first.created_at)