Okay, I didn't create this code, but I do need to find a good way to test it. We have been using factory_girl and minitest, but have a number of issues. I'm hoping to be able to move to Rspec and the Fabrication gems to setup some new tests, however I've run into a problem with cyclic dependencies. We have something like the following:
class Owner < ActiveRecord::Base
:validates has_inner?
def has_inner?
# Make sure we have an inner object
end
end
class Inner < ActiveRecord::Base
:belongs_to :owner
end
And I have Fabricators for each, something like:
Fabricator(:owner) do
inner
end
Fabricator(:inner) do
end
Anyone have any ideas on how I can pull this off? Is it possible?
I don't see any relationship defined from Owner to Inner. Is it a has_many? A little more details would be great.
Related
I have trouble with trailblazer when setting up a simple show all Things view.
operation
class Thing < ApplicationRecord
class ShowAll < Trailblazer::Operation
include Model
model Thing, :all #why :all is not working here?
def process
end
end
end
controller
class PageController < ApplicationController
def index
run Word::ShowAll
end
end
why is :all not working for getting all Things from the db but :find works to get one via its id?
The best place to ask TRB questions is actually on Github channel.
I'm not sure where you found that example, as it is not supposed to work AFAIK, :find is a shortcut I believe, I've never actually used it.
All your logic should be defined inside the process method. http://trailblazer.to/gems/operation/1.1/api.html#process
Having said that, trying to get all records without some kind of pagination is a really bad idea, unless you are 100% sure that your table won't grow beyond several dozen records. Unless you know you don't have a large load. So to define that kind of shortcut is dangerous.
Calling Trailblazer::Model#model as you're doing there is just a shortcut for overriding the TrailBlazer::Operaration#model! method. So what you seem to want to do is:
class Thing < ApplicationRecord
class ShowAll < Trailblazer::Operation
def model!(params)
Thing.all # add any filtering or pagination here
end
end
end
And in your controller call present instead of run so that it sets up the model but doesn't call the process method of the operation.
class PageController < ApplicationController
def index
present Word::ShowAll
end
end
I'm trying to create a customized ActiveRecord::Base that includes additional metadata about the connection. I see two ways to go about this:
1.) Inherit from ActiveRecord::Base and add methods & fields in this subclass.
2.) Encapsulate an ActiveRecord::Base object inside my own class
1 has all kinds of problems with the inability to override initialize, weird problems where it doesn't seem to have custom methods I've added, etc.
undefined method `set_profile' for #<Class:0xf041f0>
2 I have not been able to figure out, due to problems with using ActiveRecord::Base.new
I am trying to make an all-purpose ActiveRecord class that I can dynamically establish_connection & set_table_name on, (i.e. not have one underlying table that this ActiveRecord::Base represents) but I can't seem to find a way to accomplish it. Any ideas?
This works:
class MyTable < ActiveRecord::Base
establish_connection $config['custom-db-config'];
set_table_name 'MY_TABLE'
end
but I need a class I can call these things on repeatedly.
Not entirely sure why you'll want that, but maybe you can try this?
module ActiveRecord
class Base
def self.your_method
# implementation goes here
end
end
end
You will need to save this file and put it in config/intializers.
You can also extend the ActiveRecord::Base class in order to add the those methods dynamically which are directly callable by the class inheriting the ActiveRecord::Base...Many acts_as plugins are defined and made according to this practice...
I am trying to learn Rspec in a very simple CRUD Rails 3.2.8 app. I'm following the general pattern of Michael Hartl's examples and have been moderately successful with cucumber for the outside in portion. Now I want to test a Twilio SMS feature and cannot seem to get to first base, mostly because I'm not asking the right questions, so I expect to be corrected here and get back on track.
My app has two models, commodity and price and they interact with each other in my cucumber tests, so it appears. I'm aware, like in cucumber, I need an object to start to test its interactions. In my prices controller, I see that I can get the commodity's prices with the below in my prices#create method:
#price = #commodity.prices.build(params[:price])
I ultimately want to generate a factory that will have many prices for a given commodity. But I want to get to base first. Following thoughtbot's examples on their Readme I'm attempting the following in rails console:
FactoryGirl.create(:commodity) do |price|
Commodity.prices.build(attributes_for(:price))
end
The result is: NoMethodError: undefined method `prices' for #
Hmm, I must not be understanding either Rspec or Factory Girl. Here is my basic factories.rb:
FactoryGirl.define do
factory :commodity do
name "corn"
end
sequence :price do |n|
price
date { Time.now }
end
end
Here are my two models:
class Commodity < ActiveRecord::Base
attr_accessible :description, :name
has_many :prices
end
MOST_RECENT = 5
class Price < ActiveRecord::Base
attr_accessible :buyer, :date, :price, :quality, :commodity_id
scope :most_recent, lambda { order("id desc").limit(MOST_RECENT) }
belongs_to :commodity
end
My attempt to understand this is to do it simply in Rails console but the error also appears when I run rspec as well. But why would FactoryGirl, or Rspec, not seem to use the prices method I get with Active Record? Clearly, I'm not understanding something or I would have found the answer on Stack, thanx, sam
In your FactoryGirl.create there are a couple problems. First, the block argument should be commodity, not price. create passes the created object into the block. Second, you're trying to run prices on the Commodity class. In your object relationship, prices is an accessor associated with a specific instance. There is no Commodity#prices method, but any given instance of Commodity will have prices. You can probably use build like that, but I think the canonical way is to use the shift operator to add a Price.
Putting this together gets you:
FactoryGirl.create(:commodity) do |commodity|
commodity.prices << FactoryGirl.create(:price, commodity: commodity)
end
I'm not sure what you're doing with the sequence in your Commodity factory definition. If you're trying to make sure that Commodities are created with Prices by default (without adding them as above), check out some of the tips at http://icelab.com.au/articles/factorygirl-and-has-many-associations/.
I've tried to look through stackoverflow to remedy my situation but unfortunately I've just made myself thoroughly confused.
I have two has_many to has_many relationships: Users has_and_belongs_to_many Roles, and Roles has_and_belongs_to_many Pods. I've already set up the correct tables and everything (i.e. the role_users and pod_roles tables): I know it's at least partially working because I'm able to do #user.roles and get all of that user's roles.
However, I want to take it one step further: I want to be able to do something akin to #user.roles.pods to get all of the pods pertaining to that user. After #user.roles.pods didn't work: here's what I tried to do:
#current_user_roles = current_user.roles
#pods = Array.new
#current_user_roles.each do |role|
#pods.push(role.pods)
end
#pods.each do |pod|
puts(pod.name+"-----------------")
end
Didn't work. This is just to try to get something super simple -- to try to get all of the pods' names to appear to I can tell if it's working.
Here's something you could try:
#pods = current_user.roles.collect { |role| role.pods }.flatten
I stumbled over a SystemStackError and found where it is caused in the source code. Though, I did not quite understand why it happens. Maybe you can help me.
Here is the scenario:
There are two models Facility and Location given by their model definitions in the following.
class Location < ActiveRecord::Base
belongs_to :facility
accepts_nested_attributes_for :facility
end
class Facility < ActiveRecord::Base
has_many :locations
accepts_nested_attributes_for :locations
end
Now I create an object of each class in the Rails console: rails c.
location = Location.create(...)
facility = Facility.create(...)
Then I want to associate both with each other.
location.facility = facility
facility.locations << location
I cannot execute the last command when I executed the first before - it raises a SystemStackError: stack level too deep. Though, I can run the association commands separate from each other or sequential but in reverse order. The problem is that I cannot add the location again. Why?
Why do both?
This line:
facility.locations << location
Will already set the location's facility to be the specified facility. Both lines in this case are doing the same thing. What I would recommend doing is to use the association builder, like this:
facility.locations.create!(...)
This way, Rails takes care of setting the facility_id field, rather than you doing a manual assignment after it.
The first thing that I would suspect here is that the has_many association is really has_too_many. In other words, you may have too many locations in the relationship.
In fact, given the code you posted, you seem to have created an infinite loop of associations. You wrote:
accepts_nested_attributes_for :facility
I am assuming that this causes ActiveRecord to open the facility attribute where it finds another location with yet another facility attribute ad infinitem. before you dig too deeply, try this to see if it works:
facility.locations << location
location.facility = facility
However, be wary because this might just push the stack error to some other place in the app. If you Google for that error message you can find several people who have run into infinite recursion problems, generally related to saving a record.