Rails 3 ActiveRecord API: .build method - ruby-on-rails

I am fairly new to Ruby/RoR (outside of a year) and I have noticed that there are several different methods inside of RoR or Ruby that basically do the same thing. The one method I am wanting to get some sort of clarification on, is the .build method. when it is effective to use or how to use it in its best light, sorta thing.
Thanks!

The .build method is an ActiveRecord method which is used to create a new record based on the has_many relationship in your model.
So lets say;
User has_many tweets
Then you can use
user.tweets.build(tweet_id)
This will create a new tweet in the tweets table associated with that user. It will also return that object too.
You probably want to put a params tweet_id in you argument depending on how you are implementing the app. :)

Related

Create a model association where the model is not a active record model rails

I have a model called Client.
This extends not from ActiveRecord::Base but from my own wrapper class.
These objects are not stored in my own database.
I have some other models called Answer and Device for example. These are stored in my database with a client_id.
Now, what I want to do is that is can call Answer.client and Client.answers for example. The normal way would be with ActiveRecord associations but that doesn't work is this case.
I can define my own .answers and .client method but in my opinion that's not the way to go with Rails.
Thanks in advance for replying!

How can I get a list of the associated models that were updated during the save of an instance of ActiveRecord?

I'm passing params to a model instance and saving it with update_attributes. It is associated with several other models and I've configured it to update some of these with accepts_nested_attributes_for.
This is very nice and clean as I only have to update the one model, but I'd like to get a list of the associated(nested) models that were also updated so that I can give the user feedback about some of the fields that have changed.
Is there a way to do this, or am I approaching the problem in the wrong way?
I've found a solution to my question, maybe not the best one but it will work.
For a list of models that are associated and have accepts_nested_attributes_for configured we go:
associations = ModelClass.reflect_on_all_autosave_associations()
Each of these association objects has a name attribute(the association name), which can be used to access the association on the instance, and then we can check whether this association has changed:
associations.each{|assoc|
model_instance.send(assoc.name).changed?
}
It should be noted that we cannot use update_attributes with this solution, as all the models are saved before we can check whether anything has changed. So we have to assign_attributes and save the model in separate steps:
model_instance.assign_attributes(params[:model_instance])
// check for changes on associations here
model_instance.save()

Order by association field using ActiveRecord

Is it possible to write an ActiveRecord query that sorts by an association field if the association exists, and otherwise sorts by an attribute on the object itself?
Example: I have a Discussion object which has_many :comments. I'd like to display a list of discussions sorted by discussion.latest_comment.created_at. However, some discussions may not have any comments, in which case I would like use their discussion.created_at attribute instead.
The catch is that I need the result to be an ActiveRecord::Relation (for performance reasons, and also because we are using Kaminari [which requires a Relation object]).
The only thing I could think of is to actually create a new field like discussion.latest_comment_at which would be initially populated by discussion.created_at and then updated every time a new comment is posted. However, this doesn't seem very straight-forward from a maintenance perspective (e.g. what happens when a comment gets deleted?).
I don't know of a way to do this through SQL, so I cheated and I have my code set a last_post_at attribute whenever a topic is created.
That way, I can then sort the topics by last_post_at rather than having to query two tables at once.
I've seen other forum systems do it this way too, and it seems like what you're designing is exactly a forum-like system.

Rails convention

I'm really new to Rails (for coldfusion) and before I even start coding I want to make sure I understand the convention and apply it right.
One of my concern is the following situation using Rails convention:
I create a table called users
I create a model called User.cfc
I create a controller called Users.cfc
create a register page so I will add a method called register in the controller Users.cfc since its specifically related to the model User.
But now lets say I create a method that call multiple model then where should I put that method?
Example:
I'll take facebook wall post for this example. For each of my post many comments can be added. So I could create a method name postMessage so in that method I would call the model "Post" and also the model "Postcomment" so my question is should I put the method postMessage in the Controller "Posts" or "Postcomments"?
That really depends on the purpose of the method. If it's a user who's looking at his collection of Widgets, you might create a "widgets" method in the Users controller.
On the other hand, if you want to list all the users who bid on Widget #32, then you might add a "users" method to the Widgets controller.
There is no definite rule with these types of things. While you generally want a 1-to-1 correlation between Models and Controllers in Rails, there are exceptions. You may have some Models without their own Controllers (e.g. Login, EmailAddress), and some Controllers with no associated models (e.g. Home, Admin).

Where would a method that fetches users from an external source be placed in rails?

I have a Members ActiveRecord model and I want to create a method that would fetch members from an external source and synchronize them with the members in the database already.
I don't know where I should put that method that would be called. It seems like I shouldn't put it in the controller since it is a lot of logic, but I don't know if I can add it to the model since that seems to operate on the row only.
Any advice would be appreciated, I am new with RoR
Based only on the information you've given, I'd make it a class method for the model: def self.get_externals. That way you'd call it like Member.get_externals, and it wouldn't seem to be operating upon a single row like you're worried about.
If in doubt, stick it in lib.
Pulling from the network does not seem like it belongs in the model.

Resources