Hi Jeff
sorry for the late reply, but I have come to some solution that fits my
needs. But their are still some minor code details that need some
upgrading becouse they can lead to errors due to possible wrong user
input.
As you said, I send the data to the controller that represents the main
resource (in the example I’m giving now that will be the company
resource).
One thing that you need to know is that the related users table is build
through Javascript. This is becouse you can add/delete more/less users
dynamically.
For that, I just create a simple table, and add the rules dynamically in
the body. So on the end of the page, I do the following:
<% @company.company_roles.each do |role| %>
Company.addAssociatedUser(<%= role.to_json(:only => [ :id, :user_id,
:role_id ]) %>);
<% end %>
The addAssociateUser mehthod adds the associations dynamicaly. On my
form, I can add new rules by calling the method again, but without
parameters.
So far, so good, that works. Now I submit my form, and all the data get
send to the create/update action. To make it simple, I will show the
create action:
def create
@company = Company.new(params[:company])
if @company.save && save_user_role_associations
flash[:message] = l("company_create_response")
redirect_to(companies_url())
else
render :action => "new"
end
end
So, I create my company object and save it. But, it also calls for a
private action “save_user_role_associations”. This action looks like
this:
def save_user_role_associations
saved_ids = []
params[:company_user_association].each do |key, item_vals|
if item_vals[:id].to_i > 0
association = CompanyRole.find(item_vals[:id])
association.update_attributes(item_vals)
else
association = CompanyRole.new(:company_id => @company.id,
:role_id => item_vals[:role_id], :user_id => item_vals[:user_id])
association.save
end
item_vals.delete :id
saved_ids << association.id
end
CompanyRole.find(:all, :conditions => ["company_id = ? AND id NOT IN
(?)",@company.id, saved_ids]).each do |association|
association.destroy
end
end
This all works, as long as the user input is correct. But lets state,
that there is a wrong user input in the association data. This will
reside in an application crash, becouse the error is not caught. The
CompanyRole data doesn’t get validated and displayed if an error occurs.
The second problem lies in the create method.
@company.save && save_user_role_associations
Here the @company gets save, even if their is an error in the
save_user_role_associations action. How can I handle this?
Then another question (well, 2 question that relate to the same
problem). Lets say I have related models that I need to use. Like a
company can have a role. The roles are shown in a select, but ofcourse
we need to load the resources before we can fill them.
What I do now is create a private action in my controller that pulls all
related resources that are needed.
def relational_models
@roles = Role.find(:all)
end
So, for those resources to be available in the view, I call the
relational_models action in my new / edit action. That works like a
charm. But, the problem occurs when there is an error on the form
submit. As you can see in my above example, I redirect to the new
action. But then the related resources don’t get loaded again, and that
resides in an application crash. How can I make sure, the related
resources are loaded again properly?
The 2nd question relates to this problem. I always load custom
css/javascripts dynamically. So only when they are needed. I group my
javascript per controller.
So in overwrite the initialize action in my controller:
def initialize
super
add_styles_and_scripts
end
The add_styles_and_scripts action is again, a private action in my
controller and can look like this:
def add_styles_and_scripts
@scripts = [“company.js”]
end
This works, but again, when their is an error when the user submits
wrong data, the javascripts/css files don’t get loaded again. Its like
the initialize action doesnt get executed again.
I hope you, or someone else can help me with those problems, becouse
once they are out, I have a more solid application.
Thank you in advance