Hi, I started with Ruby on Rails a few weeks ago and am looking for a 'best practice' to handle the creation of objects that relate to eachother. I will illustrate it with an example: My model consists of 2 classes that are related, a model Businesspartner and a model Ticket. Every ticket belongs_to one Businesspartner, a businesspartner has_many tickets. The form to create a new Ticket is different for different kind of users. Users that have a role "customer" don't see anything for this relation (it is assigned when creating the ticket), users with the role "employee" get a select list of all businesspartners. There are a few things I want to check on creating a new ticket: *Check excistence of the supplied businesspartner by the form: preventing illegal input *Check if the user is a customer if this is true set the businesspartner to the default for this user: ignore the fields in the param hash Is there a best practice how to implement a thing like this? Should it be implemented in the controller or model? And are validation's usefull for this or should I handle it in the constructor or use a separate method? Currently I created a method in the model that processes the logic and returns a check instance of the Ticket , this works fine but I don't see a nice way to notify the user that one of the related fields isn't correct (I can't access the errors variable the way that validations can). I guessed this is a common challenge but haven't find any best practice on it yet. Best regards, Bart
on 2007-03-14 23:31
on 2007-03-15 00:05
On Wed, Mar 14, 2007 at 10:30:24PM -0000, Bart wrote : > My model consists of 2 classes that are related, a model > Businesspartner and a model Ticket. Assuming you have your models: class Businesspartner < ActiveRecord::Base has_many :tickets end class Ticket < ActiveRecord::Base belongs_to :businesspartner end > be implemented in the controller or model? And are validation's > usefull for this or should I handle it in the constructor or use a > separate method? First of all, the logic 'user is a customer' should be in your model. I would create a method is_a_customer in the User model so whenever I want to change conditions for a user to be a customer, I have to change it in a single place: def is_a_customer? #Your conditions, like (assuming users.customer is a boolean row): self.customer end So, you could write in your controller: def create @user = User.find(session[id]) @businesspartner = Businesspartner.find_by_name(params[:businesspartner]) unless @businesspartner if @user.is_a_customer? @user.businesspartner = @businesspartner else # I don't know, may be params.delete(:businesspartner) #blablabla end else flash[:error] = 'Illegal input!' redirect_to :action => :index end end Hope that helps, -- ,========================. | Pierre-Alexandre Meyer | | email : email@example.com | `========================'
on 2007-03-19 20:12
Thanks for your input! I have many different roles users can have, so this can become quite long. Suppose I create a Ticket object from something other than this controller (or method) then I would have to repeat the same checking. That's why I thought it would be better to implement this in the model, do you see any drawbacks on this aproach? I have also thought of implementing this as a validator; invalid objects can be created but never saved and I thought displaying the error messages could be done in the same way other validators do this, which seems logical and consistent to me. Or am I missing some drawbacks on this aproach? Bart