I am using the parseresource gem and it says I need to create a model.
Create a model:
class Post < ParseResource
fields :title, :author, :body
validates_presence_of :title
end
I only know how to generate a mode and it always inherits ActiveRecord::Base. What should I type into my command line to create this model?
I think what you are looking for is:
rails generate model Post title:string author:string blob:text
Then change the inherits from ActiveRecord to inherits from ParseResource in the post.rb file created.
class Post < ActiveRecord::Base
becomes
class Post < ParseResource
I don't really have enough details about the model or ParseResource for a better answer.
I do hope that helps though.
If you are new to Ruby and/or Rails I suggest running through an introduction to rails.
http://guides.rubyonrails.org/getting_started.html
or
http://ruby.railstutorial.org/ruby-on-rails-tutorial-book
Cheers!
In this case it looks like you only need to create a single file in your /app/models directory named after the model you're trying to create.
The normal model generation code that comes with Rails and it's generators don't apply here since this gem is specifically intended to only serve as a 'wrapper' to the Parse.com API.
From the project's home page:
ParseResource makes it easy to interact with Parse.com's REST API. It adheres to the ActiveRecord pattern. ParceResource is fully ActiveModel compliant, meaning you can use validations and Rails forms.
It looks like all you do is create a single file descending from ParseResource and then interact with it as if it were a normal ActiveRecord model.
Looks pretty straightforward, though I'd caution that the author says right in the docs:
ParseResource is brand new. Test coverage is decent.
This is my first gem. Be afraid.
Be careful and make sure you report any issues you find through the projects issues page in Github.
Unless the parseresource gem includes a custom generator, I think you will have to generate a standard ActiveRecord model and then edit it to inherit from ParseResource.
As another option you could just create the model from scratch by creating a post.rb file under app/models and putting your model code in there (any decent text editor will work just fine). Remember there is nothing forcing you to use a generator, they are just there to make your life easier.
rails generate model followed by your model name, then the fields with respective datatype and size.
Below is one exhaustive example.
rails generate model MyModel some_id:integer{20} some_name:string{255}
some_text:text some_int:integer{1} some_deci:decimal{10,2}
You can also have other data types such as boolean, date, time, datetime, float, binary.
Related
I'm using the globalize gem to translate the name attribute of my Color model. The gem seems to generate a Color::Translation ActiveRecord model, but it doesn't provide the file in app/models.
I want to add validations to this model, so I'm wondering if I can just create a file called app/models/color_translations.rb and do something like:
class Color::Translation < ActiveRecord::Base
validates_presence_of :name
end
would this extend the class's functionality (which is what I want) or overwrite everything (unwanted)?
This depends slightly on context. If there is a class Color::Translation then the result of loading your app/models/color_translations.rb file will be to add that validation. However if there is no such class, then it will define a new one.
The tricky thing in development is that classes are (in general) loaded on demand - you don't in general know what is already loaded versus what could be loaded. One way around this is to do
Color::Translation.class_eval do
validates_presence_of :name
end
which will never create a new class - it will use an existing one (if necessary Rails' autoloading will kick in) but if it can't find one it will raise an error.
The second problem you'll have is also related: if you stick this in a file in app/models how will rails know to load it if the class already exists?
It looks like globalizes creates these classes on the fly, so the safest place is to put this at the bottom of color.rb. This also ensures that if rails reloads Color and globalize thus creates a new Color::Translation that you validation will get added to this new class too.
Forgive my ignorance if I am missing something really trivial, I am very new to RoR.
Coming from Django background I remember models being like
class Post(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
both column name and field type are clearly specified.
Where as, when I write this rails command
> rails g model Post title:string description:text
all I get is
class Post < ActiveRecord::Base
attr_accessible :description, :title
end
Is there a way to write column names and field types while extending ActiveRecord::Base instead of having them only in the migration file?
Thanks, any help is appreciated
attr_accessible is deprecated and strong params replaces it functionality in the controller.
If you want to get a list of the schema information in your model file you can annotate it at the top of the file. This was best practices at some point, however I do not think it is used as much. I personally do not like this and just use the schema.
Post on best practices and annotating:
http://rails-bestpractices.com/posts/68-annotate-your-models
Gem to auto annotate:
https://github.com/ctran/annotate_models
The most wonderful thing about ActiveRecord is that you don't need to do any mapping, as all the fields are being automatically mapped using current schema. Of course default mapping can be overridden if needed, however this is a very rare case.
This approach is called "convention over configuration" and is present all over Rails - it assumes most common parameters for what you are trying to achieve so it saves a lot of unnecessary coding and mapping. It might feel weird at start, especially that you'll need to learn how to override those defaults, but I promise you are gonna love it when you get used to it. :)
I was just wondering what the recommended approach would be for validating a form that is not based on a model. I agree that generally all validation should be done in models but there are situations where a particular form might not have a corresponding model(s). For example, an arbitrary search form.
Based on my current research, there are two main ways of doing it as far as I can see,
Validate in the controller.
Is it possible to utilise the Rails validations in the controller? I really would prefer to use them over my own custom code.
Create an arbitrary class eg. called SearchForm and include the ActiveRecord::Validations
Should the class be stored with the models (even though it isn't really)?
The posts that recommended this approach indicated you have to stub out a bunch of methods for ActiveRecord such as save, save!, update_attribute, etc. This strikes me as not very Rubyesque at all!
Any other suggestions?
Absolutely #2. ActiveModel::Validations API is what you're looking for
class ArbitrarySearch
include ActiveModel::Validations
attr_accessor :query
validate :query, :presence
end
As for where this should go, yes, it should go in app/models. If you're like me and think the mix of models extending ActiveRecord::Base and those that don't coexisting within the same directory smells funny, consider adding the following to your config/application.rb file
config.autoload_paths += Dir["#{config.root}/app/models/**/"]
Now, you can organize your model files in whatever way you like. For me I have
- app
|
|- models
|
|- table
|- tableless
|- observer
and I drop classes like your ArbitrarySearch class into app/models/tableless/arbitrary_search.rb.
There is a great gem to get this and other common functionality you use within ActiveRecord models into generic non-table-based model classes called active_attr.
ActiveAttr is a set of modules that makes it easy to create plain old ruby models with functionality found in ORMs, like ActiveRecord, without reinventing the wheel. Think of ActiveAttr as the stuff ActiveModel left out.
I'm working through the Ruby on Rails tutorial and just made a Comment model with three properties.
rails generate model Comment commenter:string body:text post:references
It generated an ActiveRecord class with post but not commenter and body.
class Comment < ActiveRecord::Base
belongs_to :post
end
Why doesn't rails formally define the non-reference properties anywhere other than the DB migration scripts?
Rails dynamically loads attributes - specifically, the names of the columns and their types - based on the database schema. There is no need to define or declare them in your models. For apps running in production, it does this once, at load time. For development, it will reload them as often as every request, but only loads them when each model is used.
Rails does not infer other things from your database, though. For instance, if you were to place a unique index on a name column, it would not automatically add a validates_uniqueness_of :name to your model. Of course, the database would still enforce this constraint when you save the record, causing an exception to be raised should the name field contain a duplicate value. The recommendation, in this case, is to do both.
Why doesn't rails formally define the non-reference properties anywhere other than the DB migration scripts?
Well, where do you need them "defined" anyways? Migrations are the only place where these attributes matter coz its responsibility is to create database tables with those attributes.
If you do a scaffold on comments with similar parameters, it would also generate the views and it would be using the attributes. They don't need to be "defined" as such anywhere else.
The short answer to your question is "no". Even the migration is not a definitive place to look as there might be many migrations related to a model.
However, you may have a look at the generated "db/schema.rb" which is an aggregation of all migrations. It contains the schema definition of all activerecord models. This maybe your best bet.
Additionally, you may want to use the https://github.com/ctran/annotate_models plugin that inserts a comment in your model to help you keep track of all your model's attributes.
I have just started with Rails and coming from a .net background I find the model inheriting from ActiveRecord is hard to understand, since the don't contain the corresponding attributes for the model. I cannot imagine a new developer exposed to a large code where the models only contains references to other models and business logic.
From my point of view the DataMapper model is much easier to grasp but since ActiveRecord is the defacto standard it feels weird to change the ORM just for this little problem.
DataMapper
class Post
include DataMapper::Resource
property :id, Serial # An auto-increment integer key
property :title, String # A varchar type string, for short strings
property :body, Text # A text block, for longer string data.
property :created_at, DateTime # A DateTime, for any date you might like.
end
ActiveRecord
class Post < ActiveRecord::Base
end
I'm not sure if this is an issue and that people get used to the models without attributes, or how does experienced rails user handle this?
I don't think using the database manager or looking at loads of migrations scripts to find the attributes is an option?
Specifying attr_accessible will make the model more readable but I'm not sure if it's a proper solution for my problem?
Check out the annotate_models plugin on github. It will insert a commented schema for each model in a comment block. It can be installed to run when migrate is.
You don't have to "look at loads of migration scripts to find the attributes" - they're all defined in one place in db/schema.rb.
A few tips:
Load up the Rails console and enter
Post.column_names for a quick
reminder of the attribute names.
Post.columns gives you the column
objects, which shows the datatypes
db/schema.rb contains all the
migration code in one place, so you
can easily see all the column
definitions.
If you are using a
decent editor/IDE there should be a way to
allowing you to jump from the model file
to the migration file. (e.g. Emacs
with ROR or Rinari)