rspec controller post action test fails with ActiveModel::ForbiddenAttributesError - ruby

I want to test the post action of my controller but it fails with an ActiveModel::ForbiddenAttributesError.
require 'spec_helper'
describe HomeController do
describe "POST #create" do
context "with valid attributes" do
it "saves the new feed in the database" do
expect{
post :create, feed: FactoryGirl.attributes_for(:valid_feed)
}.to change(Feed,:count).by(1)
end
end
end
Factory:
FactoryGirl.define do
factory :valid_feed, class: Feed do
title "CRE"
address "http://cre.fm/feed/m4a/"
end
factory :invalid_feed, parent: :valid_feed do |f|
f.address nil
end
end
Controller:
class HomeController < ApplicationController
def index
end
def create
#feed = Feed.new(params[:feed])
if #feed.save
redirect "/"
else
render nothing: true
end
end
end
I checked the params in controller to see if there is something wrong but params[:feed] contains a valid hash.
Did I miss something here?

Yup, you missed something. Rails 4 has enabled strong parameters by default. You'll need to change it to something like this:
class HomeController < ApplicationController
def index
end
def create
#feed = Feed.new(feed_params)
if #feed.save
redirect "/"
else
render nothing: true
end
end
private
def feed_params
params.require(:feed).permit(:allowed, :elements, :of, :feed)
end
end

Related

how to display json and parse json in ruby using httparty

I am working on a food app in ruby on rails which requires to get calorie value of food item from food api.In my controller i am getting the JSON response but i am unable to parse and display the calorie value of food item in a index.html.erb file here is my controller code.
require 'rubygems'
require 'httparty'
class FoodsController < ApplicationController
def index
#foods = Food.all
end
def show
#food = Food.find(params[:id])
end
def new
#food = Food.new
end
def edit
#food = Food.find(params[:id])
end
def create
#food = Food.new(food_params)
#response = HTTParty.get('http://api.nutritionix.com/v1_1/search/'+#food.name+'?fields=item_name%2Citem_id%2Cbrand_name%2Cnf_serving_size_unit%2Cnf_calories%2Cnf_total_fat&appId=696d1ad4&appKey=aec2c4766d40d7f6346ed89d5d82fe75')
#http_party_json = JSON.parse(#response.body)
if #food.save
redirect_to foods_path
else
render 'new'
end
end
def update
#food = Food.find(params[:id])
if #food.update(food_params)
redirect_to #food
else
render 'edit'
end
end
def destroy
#food = Food.find(params[:id])
#food.destroy
redirect_to foods_path
end
private
def food_params
params.require(:food).permit(:name, :quantity)
end
end
Any suggestions are highly welcome as i am newbie on stackoverflow so dont know proper editing forgive please! help me how to display calorie value in html page
You can add a new function to Food model to get you the Calorie:
class Food
def calorie
response = HTTParty.get("http://api.nutritionix.com/v1_1/search/#{self.name}?fields=item_name%2Citem_id%2Cbrand_name%2Cnf_serving_size_unit%2Cnf_calories%2Cnf_total_fat&appId=696d1ad4&appKey=aec2c4766d40d7f6346ed89d5d82fe75")
json = JSON.parse(response.body)
end
end
and then simply in your index.erb if you loop over foods collection you do the following:
<% #foods.each do |food| %>
<%= food.name %>
<%= food.calorie %>
<% end %>
but in that case performance will not be good, as you do remote access for each item each time you display data, so as calorie value is always the same for same food, then after its created you can do remote query and store the calorie to calorie attribute in your Food model
You can do the following:
class Food < ActiveRecord::Base
before_create :set_calorie
private
def set_calorie
response = HTTParty.get("http://api.nutritionix.com/v1_1/search/#{self.name}?fields=item_name%2Citem_id%2Cbrand_name%2Cnf_serving_size_unit%2Cnf_calories%2Cnf_total_fat&appId=696d1ad4&appKey=aec2c4766d40d7f6346ed89d5d82fe75")
self.calorie = JSON.parse(response.body)
end
end

Sinatra App - Separating Concerns

Probably something really basic, but I want to be able to separate my Sinatra routes from controllers. I have this code in my routes.rb:
require 'sinatra/base'
class Server < Sinatra::Base
get '/' do
Action.index
end
end
This is my controller/server.rb
class Action
def sef.index
#user = User.new("Abiodun Shuaib")
haml: index
end
end
It gives the error undefined method 'haml' in Action:Class.
How can I fix this?
You are trying to access method haml in class Action. It simply doesn't contain it.
For example, you can do:
class Server
def index
#user = User.new("Abiodun Shuaib")
haml :index
end
end
By doing this, you will add to Server method index.
Or you can do in such way(it's called Mixin):
module ActionNew
def index
#user = User.new("Abiodun Shuaib")
haml :index
end
end
class Server < Sinatra::Base
include ActionNew
get '/' do
index
end
end

Test helpers with RSpec in Padrino (Sinatra)

I'm trying to test a helper in a Padrino (Sinatra) app. My helper method is itself calling Padrino core helper methods but they are undefined. The error appears only in RSpec, while the app works fine. So the way I'm including my helper in RSpec makes it loose "Padrino scope" but I don't know how to bring Padrino helper's scope properly in my RSpec environment.
My helper:
module AdminHelper
Sort = Struct.new(:column, :order)
def sort_link(model, column)
order = sorted_by_this?(column) ? 'desc' : 'asc'
link_to mat(model, column), url(:pages, :index, sort: column, order: order)
end
def sorted_by_this?(column)
column.to_s == #sort.column && #sort.order == 'asc'
end
end
Lenstroy::Admin.helpers AdminHelper
My spec:
describe AdminHelper do
before(:all) do
class AdminHelperClass
include AdminHelper
end
end
subject(:helper) { AdminHelperClass.new }
describe '#sort_link' do
context "with :pages and :title parameters" do
before do
sort = AdminHelperClass::Sort.new('title', 'asc')
helper.instance_variable_set('#sort', sort)
end
subject { helper.sort_link(:pages, :title) }
it { should match(/<a href=([^ ]+)pages/) }
end
end
end
Results in error:
1) AdminHelper#sort_link with :pages and :title parameters
Failure/Error: subject { helper.sort_link(:pages, :title) }
NoMethodError:
undefined method `mat' for #<AdminHelperClass:0x007f1d951dc4a0>
Including a helper where mat is defined doesn't work, as one method is dependent on another helper and it goes on and on...
Update
In my spec helper I have:
def app(app = nil, &blk)
#app ||= block_given? ? app.instance_eval(&blk) : app
#app ||= Lenstroy::Admin
#app.register Padrino::Helpers
#app.register Padrino::Rendering
#app
end
in my spec I have:
it "returns link to resource with sort parameters" do
app do
get '/' do
sort_link(:pages, :title)
end
end
get "/"
last_response.body.should =~ /<a href=([^ >]+)pages/
end
And now tests fail, last_response.body is ''.
Method #mat is defined in Padrino::Admin::Helpers::ViewHelpers. You can do
class AdminHelperClass
include Padrino::Admin::Helpers::ViewHelpers
include AdminHelper
end
Update:
If your methods are really dependent on all these routes and helpers you should consider doing full mockup of your app like this:
def mock_app(base=Padrino::Application, &block)
#app = Sinatra.new(base, &block)
#app.register Padrino::Helpers
#app.register Padrino::Rendering
# register other things
end
def app
Rack::Lint.new(#app)
end
mock_app do
get '/' do
sort_link(my_model, my_column)
end
end
get "/"
assert_equal "some test text", body
Here's how it's done in padrino-admin: https://github.com/padrino/padrino-framework/blob/master/padrino-admin/test/test_admin_application.rb
I was having the same problem (and getting very frustrated tracking down the modules and including them). So far, I've got my specs working by:
1) Explicitly defining my module (as explained in how to use padrino helper methods in rspec)
module MyHelper
...
end
MyApp::App.helpers MyHelper
2) Automatically including helpers at the top of my spec. (Right now I only have one helper spec, but in the future I might try to move this into spec_helper.rb.)
describe MyHelper do
let(:helpers) { Class.new }
before { MyApp::App.included_modules.each { |m| helpers.extend m } }
subject { helpers }
it 'blah' do
expect(subject.helper_method).to eq 'foo'
end
end

Rails 4 strong parameters ActiveModel::ForbiddenAttributesError

For some reason in my current controller I am getting ActiveModel::ForbiddenAttributesError even though I believe I am using strong parameters just fine. Albeit I am using permit! for the time being to permit all model attributes. See code below, what am I missing
class HeuristicsController < ApplicationController
def index
#heuristics = Heuristic.order(:name).page params[:page]
#heuristic = Heuristic.new
end
def create
#heuristic = Heuristic.new(params[:heuristic])
if #heuristic.save
redirect_to action: 'index', :flash => {:success => "New heuristic created!" }
else
render 'new'
end
end
def new
#title = "Heuristic"
#heuristic = Heuristic.new
end
private
def heuristic_params
params.require(:heuristic).permit!
end
end
i think you did not fully understand the way that strong-params work...
you have a method
def heuristic_params
params.require(:heuristic).permit!
end
and you are not using it
Heuristic.new(params[:heuristic])

How do I write functional test for this

I am pretty new to rspec. How do I write functional test for following piece of code.
class FooController < ApplicationController
 def new
#title = "Log in to Mint"
#msg = session[:msg]
session[:msg] = nil
end
end
 
How about something like this:
describe FooController do
describe "GET new" do
it "assigns 'Log in to Mint' to #title" do
get :new
assigns(:title).should == "Log in to Mint"
end
it "assigns message session to #msg" do
session[:msg] = "a message"
get :new
assigns(:msg).should == "a message"
end
it "sets message session to nil" do
get :new
session[:msg].should be_nil
end
end
end
See also: Rspec: testing assignment of instance variable

Resources