I have updated active record from 3.2.12 to 4.1.4. Accordingly I have update activesupport also from 3.2.12 to 4.1.4. Now when I do data base queries (h2-data base) I cannot use
mrs = MeasurementResultSample.find_by_duration_and_measurement_result_id(duration, id)
I can oly use
mrs = MeasurementResultSample.where(:duration => duration, :measurement_result_id => id).first
The activerecord-jdbch2-adapter I have upgraded from 1.2.9 to 1.3.9
How can I make my 'find_by' methods using one or more fields working again?
Update:
actually it turned out, that find_by is working but I had to check if the table exsist with the method exists?. What wont work is find_last_by... or find_all_by... or find_first_by... .
As I understand it, Rails is moving away from certain 'magic' method names due to the poor performance of 'method_missing,' upon which they're based.
However, find_by works. So you can re-work your query with:
mrs = MeasurementResultSample.find_by(duration: duration, measurement_result_id:, id)
Amusingly, the implementation behind the scenes is:
def find_by(*args)
where(*args).take
end
http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find_by
Edit:
There's a gem that includes Rails 4 deprecated finders:
https://github.com/rails/activerecord-deprecated_finders
Confusingly it states that find_by... methods aren't deprecated. However, if you've updated ActiveRecord outside Rails it might help.
If not, you could always look at the Rails 3 ActiveRecord code and port the relevant methods across.
Thanks to A Fader Darkly! I finally started to port the code to activerecord 4.1.4. I opted to change the finder methods to where(...).
Here I found some information too what-s-new-in-active-record-rails-4.
It's the cleanest way. I noticed, that I had to use the exist? method in some cases to make sure the table is not nil. I did not have to do this before (in 3.2.12) with inflections used.
Related
I'm writing a Ruby gem that requires to make a very simple query to an unknown database among the next: sqlite, mysql, postgresql.
For now I'm using ActiveRecord to handle this idiosyncrasy but looks like a bit overwhelming for me since I'm not using 99% of the ActiveRecord power.
I need something to play with in the next way:
connection = AbstractConnection.new("adapter", "database" {, "username", "userpass"})
connection.query("select * from table")
Is there any gem that abstracts me of generating the connection to different adapters? Is it using ActiveRecord a good idea here?
If you don't want to use ActiveRecord, you could use:
Sqlite3 gem
MongoDB driver
Pg gem
MySQL driver for Ruby
ActiveRecord provides a much nicer DSL across databases, but if you don't need all the overhead then you might want to invest some time in picking up one of the above.
If, however, you think that you may want to change database type in the future, then I recommend you use ActiveRecord: your code will stay the same and the underlying framework will deal with the changed database type.
Hope this helps!
Question:
In a post-attr_accessible Rails 4 world, in what way do you recommend, if at all, annotating your ActiveRecord model class files to communicate its (database) attributes?
Further Thoughts
As part of a Rails 3 -> 4 upgrade, we are making a switch, and happily so, away from attr_accessible and to strong parameters in the controller. I understand and agree with the improvement in security via this switch. If you want to know more about this, the information is out there, and it's not hard to find.
But, I enjoyed, in my Rails 3 world, having those reminders of what attributes made up a class up there at the top of the model file. Especially since we're moving toward a world in which ActiveRecord classes are just DAOs, what else is the class but a collection of database attributes? I don't want to go to the schema.rb file just to remember them.
Am I thinking about this incorrectly? In a DAO world, should I be creating my ActiveRecord model class file and then never opening it again?
I know about the annotate_models gem and used it way back in the day. I was not a fan of having the attributes described in commented-out lines. (unreadable, hackish, fragile)
Thoughts? Opinions?
How about:
Person.column_names
If you are using an IDE or and editor that has a console feature this becomes an easy way to be reminded what attributes there are. I am no Ruby or Rails expert, still pretty new here, but I've been using Rails 4 almost exclusively and it just seems like you wouldn't need to see the attributes that often in the model. The params get whitelisted in the controller because that is where they will usually be used, no? If you don't want to use comments you could store an array of the attributes in the model:
my_attr = [:fname, :lname, :age, :height, :weight]
But is that really any more useful than a comment? Would there be a case of attributes that would have been in attr_accessible that wouldn't be in your whitelist in your controller? It would be trick if you put some code in a rake task that would run every time you ran
rake db:...
that would update the my_attr array in your model so you wouldn't have to remember to do it when you modified the model. I go into my models to add class methods and scopes, so I do see a value in it. But I work in RubyMine so I just click on the DB tab on the left side if I need to be reminded of columns that aren't in my whitelist.
I have an ActiveRecord based application that is used via command line utilities. Having the models namespaced in such an application is advantageous for keeping the Object namespace clean.
I'm starting to build a rails application around these ActiveRecord models and, though I have overcome some of my initial troubles with using models in a namespace, I'm finding things are more verbose than I'd like.
What I want is to programmaticaly set a namespace for my ActiveRecord classes when used in the command line utilities and to programmaticaly not set a namespace for these models when used in the Rails app.
I know that the files themselves could be altered at runtime before being required, but I'm looking for something in the Ruby language itself to accomplish this cleanly.
hard to offer a great suggestion without seeing some code, but here are two possibilities.
It sounds like you have two clients for this code. Maybe make it an engine (just a fancy gem), you can add your paths to autoload paths, then use it from the gem without all the railsy crap getting in the way.
Maybe create a constant then reopen it in the models:
in some initializer
ActualNamespace = Class.new
DynamicNamespace = ActualNamespace
in your model file
class DynamicNamespace
class MyModel
end
end
DynamicNamespace::MyModel # => ActualNamespace::MyModel
Then for your command line app
DynamicNamespace = Object
Which is the same as not having a namespace:
DynamicNamespace::MyModel # => MyModel
Now you might wind up having difficulties with some of the Rails magic, which is largely based on reflection. I don't totally know what you'll face, but I'd expect forms to start generating the wrong keys when submitting data. You can probably fix this by defining something DynamicNamespace.name or something along those lines.
Autoloading, is likely to also become an issue, but I think you can declare autoload paths somehow (I don't know for sure, but googling "rails autoloading" gives some promising results, looks like it just hooks into Ruby's autoloading -- though I think this is going away in Ruby 2.0) worst case, you can probably define a railtie to eager load the dirs for you. This is all a bit out of my league, but I'd assume you need the railties defined before the app is initialized, so you may need to require the railtie in config/application.rb
Unfortunately, at the end of the day, when you start deviating from Rails conventions, life starts getting hard, and all that magic you never had to think about breaks down so you suddenly have to go diving into the Rails codebase to figure out what it was doing.
I'm trying to create a Rails app without a persistence layer (ActiveRecord, MongoMapper, etc). I've used --skip-active-record on rails new nice_app. This has changed the config/application.rb, but when I try to create new "model" with Rails generate - rails g model nice_class - it fail like a noob with:
No value provided for required options '--orm'
So, if I skip ActiveRecord I can't use Rails generators ?
Note the tasks that get called when you run rails g model nice_class:
invoke active_record
create db/migrate/20111227183458_create_nice_classes.rb
create app/models/nice_class.rb
invoke rspec
create spec/models/nice_class_spec.rb
The first thing you notice, is that it's using ActiveRecord to generate the model. Besides that, though, it's not doing a lot: creates a file in the migrations folder (which you don't need), another file in the model folder (which you do need), and a file in the test or spec folder (which you 'should' need). You can make these yourself if you want want, they are pretty close to being empty anyway.
For specifics about models not based on ActiveRecord, take a look at Ryan Bates' "Tableless Models" Railscast available here: http://railscasts.com/episodes/193-tableless-model.
If you are going to be making these kinds of non-ActiveRecord models a lot, you can write your own generator that does exactly what you want.
Best of luck.
The models that are generated by the Rails generators are subclasses of ActiveRecord, which only really makes sense in the context of an app with an ORM. You could certainly create models that aren't subclasses of ActiveRecord (and thus not associated with any ORM), but you'd have to do that manually.
I would like to skip/disable ActiveRecord callbacks in, specifically, Rails 3. The following is an example solution I thought of -- creating an attribute that is defined to create the object without callbacks.
product = Product.new(title: 'Smth')
product.send(:create_without_callbacks)
The above example is similar to that in this answer, but the author said it is for specifically Rails 2. Is there a similar, or even better, way to do this for Rails 3?
See the question: How can I avoid running ActiveRecord callbacks?
This blog post has another explanation with example.
You may find the solution here helpful: http://manuelvanrijn.nl/blog/2012/01/12/disable-rails-before-slash-after-callback/
TL;DR - If you are doing this production, it may be helpful to create a class (see blog post) to keep your code DRY. Otherwise, if you do this once, or even in testing (like myself), you can simply do the following:
SomeModel.skip_callback(:save, :before, :before_action)
SomeModel.skip_callback(:save, :after, :after_action)
The blog post provides a nice list of callbacks the above method will work with.
This will work in both Rails 3 and Rails 4. As noted by a comment, if you have to disable callbacks, you may want to ask yourself why you need those callback. To expand, disabling callbacks are questionable only in production. If you need to disable them in testing (which is what I am doing myself), it is acceptable... Especially since Rails 4 core deprecated the use of observers.
SomeModel.skip_callback(:save) do
somemodel_instance.save
end
tested: Rails 4.2.1