This is something I want to do but I can't figure out if it is possible.
I would have two Ruby classes (SuperNes and MegaDrive) that include the same Module (Console).
So I assume there will be common attributes and a few particular ones. I would like to store it in the same MongoDB Collection (with the store_in helper).
How will I ensure that, for example, SuperNes.all will return only SuperNes data and not MegaDrive ?
Thank you for your answers and for the time you spent reading me !
May be you can try inheritance in mongoid ,
class Console
include Mongoid::Document
end
class SuperNes < Console
end
class MegaDrive < Console
end
Related
I am using mongoid with rails 3 and have come lately to a very tough
problem and I need an advice.
I am working on a CMS and one of the ideas was that CMS would provide
some basic models definitions and end user would, if needed, extend
basic class with its own definitions and controls and save them in different collections (tables).
class DcPage
include Mongoid::Document
field a ....
belongs_to b ....
validates a ....
end
class MyPage < DcPage
field c ....
validates c ....
end
Up until last version of mongoid this worked (with little hack) and data
would be saved to my_pages collection. Because of some problem, mongoid no
longer support this behaviour and data always gets saved to dc_pages
collection.
When explaining my problem, mongoid team suggested that I use
ActiveSupport::Concern and provided me with an example. Which works
perfectly OK if extended class is defined in same source file. Which
btw. never happens in praxis.
module CommonBehaviour
extend ActiveSupport::Concern
included do
field :subject, type: String, default: ''
# ...
end
end
class DcPage
include Mongoid::Document
include CommonBehaviour
end
class MyPage
include Mongoid::Document
include CommonBehaviour
end
So far I have found out that it works if I require basic source file in
my second file. Which looks like this:
require '/some/path/to/my/gem/app/models/dc_page.rb
Can you can see my pain now. Basic source file would of course be backed into
gem and therefor becomes a moving target.
Please help me with better solution.
by
TheR
The reason this doesn't work is because this is the pattern for single table inheritance.
You would need to turn off table inheritance in order for this to work.
However, the suggestion from the mongoid devs is the correct route to go in this case.
It looks like you just need to require your module/classes correctly.
Acutally i face some hard exercises in computer science (hard for me i think, haha).
We're doing some basic stuff with Ruby on Rails an i have to open a csv file to get additional information on my 'User' model which is a normal rails scaffold.
So at the moment i open the csv file in my users_controller.rb file and search for the right row an add them to an instance variable.
But i wonder if i can write a class that acts like an ActiveRecord Model. So i change the code to use ActiveModel. But as i read in some google results, ActiveModel can't make use of ActiveRecord like associations. But it would great to have them.
So i hope you can help me. How can i provide my model with ActiveRecors like associations?
Greetings
Melanie
It's absolutely right that the CSV file should be represented as a model, as it's data.
However, trying to incorporate Active Model sounds tricky and would almost certainly require a great deal of hacking or monkey patching.
Unless you really need associations to other models, I would create a standalone class (i.e. not inheriting from ActiveRecord::Base) in the models directory, and put the logic for parsing the CSV in there:
class User
attr_accessor :name, :email, ...
def initialize(name,email,...)
# set data
end
def self.find(param_for_search)
# Parse CSV file, find line you want
# return a User instance
self.new(name, email)
end
end
I don't know exactly how your system works, but this way you can make it behave in a similar way to Active Model stuff. You can add similar class methods and each instance method represents a CSV file row.
Every time , when you are creating your own model , it is inheritance of ActiveRecord :
class Project < ActiveRecord::Base
attr_accessible :content, :name, :user
end
Then you can tell your model to have many (let's say) Project's Tasks , which creates an association . Please , provide an example of your app's logic.
Here is a quote from RailsCasts.com :
"In Rails 3 the non-database functionality of Active Record is extracted out into Active Model. This allows you to cleanly add validations and other features to tableless models."
There is also a nice description how to add functionality in you model by adding modules .
I understand, that using ActiveRecord to use an non database source is difficult, but i think it would be vewy charming if i could write something like this:
user.worktimes.first.value
in my view and get the information like it is a database table. I visit railscast.com an i found a episode where this ist discussed. But i would like to digg deeper in this. Are there any further ressources i could read?
As i understand, ActiveModel does not support associations? I wonder why associations wasn't moved to ActiveModel as it is a very useful thing. :)
So here is my code, that i was working on:
User-Model:
class User < ActiveRecord::Base
attr_accessible :department_id, :name
belongs_to :department
end
Department-Model:
class Department < ActiveRecord::Base
attr_accessible :name
has_many :users
end
And here is my CSV Model, that i created:
class Worktime
attr_accessor :user_id,:date,:value
def initialize(params)
dir = Rails.root.join('app', 'models', 'worktimes.csv').to_s
source = File.open(dir,'r')
while(line=source.gets)
data = line.split(';')
if data[0] = params[:user_id] && data[1] = params[:date]
#value = data[2]
end
end
end
end
I am very thankful for your help as its my first time using rails.
I have been researching on the best approach for my problem which I originally had implemented as a single table inheritance but am deeply concerned about the scalability, as potentially will have thousands of columns in the table.
So the problem is I would like to have products which the methods of each are exactly the same the only difference being the attributes each one contains. It seems that in this situation that mutli-class inheritance (not supported natively in rails?) would be the best approach or some sort of polymorphic associations.
I want to work towards the following
#product.rb
Class Product < ActiveRecord::Base
attr_accessible :title .....
def to_s # some arbitrary method used by all extending classes
....
end
end
#book.rb
class Book < Product
attr_accessible :author...
end
So I want the book to inherit the methods from product and not for the product to know about the attributes required by each subclass. And if possible get all of the products through one query.
I need to know the best way of approaching this, and if I am doing it completely wrong, please note the code written above is just for example to simplify my problem.
What you can do is create a module and include it in several different models.
First, create a file in your lib directory
i.e.) my_module.rb
module MyModule
def full_name
"#{first_name} #{last_name}"
end
end
Then, make sure the module is loaded when your Rails App starts:
In config/application.rb:
config.autoload_paths += %W(#{config.root}/lib)
Finally, include it in your models:
i.e.) app/models/thing.rb
class Thing < ActiveRecord::Base
attr_accessible :first_name, :last_name
include AdditionMod
end
You can test it in the console:
#thing = Thing.create(first_name: "Awesome", last_name: "Module")
#thing.full_name
=> "Awesome Module"
Found out that I can use H-store in conjunction with postgres that allows me to have a column that contains a schema less hash that can be used with the power of postgres (for an example take a look at http://hstoredemo.herokuapp.com/)
I'm trying to create an application that has forms, who have questions, who, in turn have answers. The questions require a different type of answer, e.g. free text or a choice from a set of possible choices (multiple choice question). Different types of questions inherit from the base class Question. It's the multiple choice questions that are proving problematic.
There are going to be multiple choice questions with different sets of possible answers (say, 1-5, 1-8 or yes/no). I was thinking of creating a class MultipleChoiceQuestion < Question, and the answer choices are given as an array and then saved to the database using serialization. I am, however, unable to get the serialization working at all.
From googling around, I've figures that serialization should work by writing:
class MultipleChoiceQuestion < Question
serialize :choices, Array
end
Now if I open rails console, and type
q1 = MultipleChoiceQuestion.new
q1.choices
I only get a NoMethodError on choices. Is there something else I need to do to get serialization working? I've also tried adding a text column "choices" in the database by editing the migration file and migrating the database, but it doesn't help either.
I'm using Rails 3.2.6 and PostgreSQL 9.1.
Update: If I change the MultipleChoiceQuestion class to inherit from ActiveRecord::Base instead of Question, serialization works. But Question inherits from ActiveRecord::Base, so I don't understand what the problem is.
I usually do something like this:
class User < ActiveRecord::Base
serialize :preferences, Hash
end
def preferences
read_attribute(:preferences) || write_attribute(:preferences, {})
end
to ensure that its default vaue is what you expected. And I mark the column of type text that is being serialized so attribute is stored as yaml.
user.preferences[:key] = value
You could also add a new model (and some database tables) for the choices, e.g.:
class Choice < ActiveRecord::Base
belongs_to :multiple_choice_question
end
class MultipleChoiceQuestion < Question
has_many :choices
end
I have a rails app with some nested data that I'd like to export as a CSV file
The models look like:
class ContainerRecord < ActiveRecord::Base
has_many :child_records
and
class ChildRecord < ActiveRecord::Base
belongs_to :container_record
I'd like to be able to export a CSV file with each ContainerRecord on a row with its information in the first few columns and a value from each ChildRecord in the remaining columns.
I can't guarantee the number of ChildRecords associated with each ContainerRecord and I don't care if I have a different number of non-null columns for each row.
I've attempted to use FasterCSV, but I get all of the data for the child records shoved into one column rather than a column for each.
Is this something that I can do with FasterCSV? If not, what method can I use to accomplish my goal?
Not sure about FasterCSV but a quick & dirty solution could be:
class ParentClass < AR::Base
has_many :children
def self.csv
all.map do |object|
( object.attributes.values + object.children.map(&:child_field) ).flatten.join(',')
end.join("\n")
end
end
Replacing "child_field" with the field you want to take from your child model of course.
I ended up finding a nice tutorial on csv_builder that let me do exactly what I wanted to do with minimal effort and allowed me to stick a little more closely to the MVC architecture.