I have a simple Rails 3.2 controller which is consumed as an API with JSON:
module Api
module V1
class ReportsController < Api::V1::ApplicationController
def index
respond_with Report.where(name: params[:name])
end
end
end
end
(there is no code is the parent controllers)
When I consume this method, I'm getting all reports back, as expected, but I'm also getting all the associations. I don't see why this is and want to stop it.
Why am I getting the associations?
As #rmagnum2002 eluded to, I found active_model_serializers bundled into the app, and someone had created a serializer for that model without me noticing it.
Related
On Rails 4.1 .. being new to Spree 2-3-stable and experimenting with various things. My test store works fine and now I would am trying and integrate it into my application which is a booking site.
On my Bookings calendar I would like users to click on a booking link and have that auto populate their cart, then show their cart directly.
So assuming I have a spree product, and a variant existing in the database, and the current_user is logged in (ie spree_current_user exists) .. I thought this would be possible but it seems it will not even create the populator.
class BookingsController < ApplicationController
def add_booking_to_cart
populator = Spree::OrderPopulator.new Spree::Order.current_order(create_order_if_necessary: true), current_currency
# .. get variant related to booking
# .. add varient to populator
end
#... rest of bookings controller
end
Errors out with:
NoMethodError - undefined method `current_order' for #<Class:0x00000007d4fc68>:
I am attempting to do a similar thing to what Will is doing here but am getting the error undefined method on current_order object. My understanding of the code is that it should create a new order if necessary, ie if one does not exist. No sure what do to here? Any pointer would be greatly aprecieated.
https://github.com/spree/spree/blob/2-3-stable/frontend/app/controllers/spree/orders_controller.rb#L46
For this to work your controller needs to extend Spree::StoreController
class BookingController < Spree::StoreController
This is where the method is defined in Spree:
https://github.com/spree/spree/blob/master/core/lib/spree/core/controller_helpers/order.rb
Also, you might need to have a before_filter :set_current_order.
I've just started using the Pundit gem for authorisation in a Rails 4 app.
Everything's going fine but I can get my head around how pagination will work in the index action.
My controller's index action looks like:
def index
#records = policy_scope(Record)
end
The Scope class within my RecordPolicy then goes:
class Scope < Struct.new(:user, :scope)
def resolve
if user.has_role? :admin
# get all records
else
# get user specific records
end
end
end
This all works fine. I'd like to know how I would handle pagination though. Naturally this involves passing in a page parameter etc and I'm not sure how to do this without subsclassing the Scope class.
The policy_scope(Record) method returns an ActiveRecord::Relation object, then you can chain the pagination method, depending on which gem you use (will_paginate, kaminari).
def index
#records = policy_scope(Record).paginate(params[:page])
end
For googlers. The answer above is technically correct, but with most recent versions of Kaminari (mine is 0.17), the method to chain is page(params[:page])
Hey I am creating a rails 3 engine and trying to access a model in the application that is mounting the engine.
module MyEngine
class UsersController < ApplicationController
def index
#users = User.all
end
If I call the following then it gives me the error:
Could not find table 'my_engine_users' - Its automatically looking for the namespaced version that would exist if the model was inside the engine, but in this case its defined in the app that uses the engine.
If I call ::User.all instead of User.all then everything works, it looks a bit strange though. Is this valid ruby or is there a better way to get ahold of the Object?
So if I get your question right, you have a model in your engine looking something like this:
module MyEngine
class User
end
end
If the assumption above is right, you can just set the table name via table_name= in the model
module MyEngine
class User
self.table_name = 'users'
end
end
This is going to sound strange, but hear me out...I need to be able to make the equivalent of a POST request to one of my other controllers. The SimpleController is basically a simplified version of a more verbose controller. How can I do this appropriately?
class VerboseController < ApplicationController
def create
# lots of required params
end
end
class SimpleController < ApplicationController
def create
# prepare the params required for VerboseController.create
# now call the VerboseController.create with the new params
end
end
Maybe I am over-thinking this, but I don't know how to do this.
Inter-controller communication in a Rails app (or any web app following the same model-adapter-view pattern for that matter) is something you should actively avoid. When you are tempted to do so consider it a sign that you are fighting the patterns and framework your app is built on and that you are relying on logic has been implemented at the wrong layer of your application.
As #ismaelga suggested in a comment; both controllers should invoke some common component to handle this shared behavior and keep your controllers "skinny". In Rails that's often a method on a model object, especially for the sort of creation behavior you seem to be worried about in this case.
You shouldn't be doing this. Are you creating a model? Then having two class methods on the model would be much better. It also separates the code much better. Then you can use the methods not only in controllers but also background jobs (etc.) in the future.
For example if you're creating a Person:
class VerboseController < ApplicationController
def create
Person.verbose_create(params)
end
end
class SimpleController < ApplicationController
def create
Person.simple_create(params)
end
end
Then in the Person-model you could go like this:
class Person
def self.verbose_create(options)
# ... do the creating stuff here
end
def self.simple_create(options)
# Prepare the options as you were trying to do in the controller...
prepared_options = options.merge(some: "option")
# ... and pass them to the verbose_create method
verbose_create(prepared_options)
end
end
I hope this can help a little. :-)
I am upgrading a Rails application from 2.3.10 to 3.0.4 and am running into an issue with updating models in my controller. I have been "scoping" model finds in order to prevent users from updating objects that don't belong to them. It works as expected in 2.3, but I get an ActiveRecord::ReadOnlyRecord error with update_attributes in Rails 3.
What is the right way to do this in Rails 3?
Project controller:
def update
#project = current_user.projects.find(params[:id])
if #project.update_attributes(params[:project])
# saved
else
# not saved
end
end
It turns out it was related to using scopes to impersonate active record associations. I was able to fix it by adding .readonly(false) to my scopes.
One possible solution is create new file config/active_record_monkey_patch.rb and add following content in it.
module ReadOnlyFalse
def self.included(base)
base.class_eval do
def readonly?
false
end
end
end
end
ActiveRecord::Base.send(:include, ReadOnlyFalse)
above code work for all models readonly(false).