0

I have a Workflow model, an Action model, and a Role model. Actions are nested attributes of a workflow, and an action has and belongs to many roles.

The associations work fine. However, in my form view, I need to add a role to the last action that has been build (note but not created).

The Workflow controller:

def create
  @workflow = Workflow.new(workflow_params)
  if params[:add_role] # from a submit button
    Action.last.roles << Role.find(params[:role_id])
    # doesn't work as no actions have been created

    ...

  elsif params[:add_notify_action]
    @workflow.actions.build         # cannot save because parent hasn't been saved          

end

In short, how do I get to the last Action that has been built in my controller? By definition, it's not in the database.

In long, if I can't, what's another option to get the roles added to the actions?

Rishi
  • 945
  • 2
  • 15
  • 23
  • 1
    what about saving the the workflow first and only adding roles if the workflow is valid? – engineersmnky Jul 25 '14 at 19:25
  • If an Action is a nested attribute of Workflow, when you initialize a new workflow passing the params, don't you initialize a new Action? Then you could just go ahead and do: @workflow.action to access the Action. But before adding the persisted Roles, you'll need to also persist the action. Does it make sense? – Tiago Farias Jul 25 '14 at 19:34
  • @engineersmnky I would prefer to avoid saving the workflow first because then the user would have to fill out a name and description because I'm validating for the presence of those attributes. – Rishi Jul 25 '14 at 20:26
  • @TiagoFarias that seems like the way to go but how would I grab the last action I added? – Rishi Jul 25 '14 at 20:27
  • also @TiagoFarias I think your comment could count as an answer consider making it one? – Rishi Jul 25 '14 at 20:27
  • 1
    What do you mean by last action added? Workflow has_many Actions? – Tiago Farias Jul 25 '14 at 20:32
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/58026/discussion-between-rishi-and-tiago-farias). – Rishi Jul 25 '14 at 20:41

2 Answers2

1

If an Action is a nested attribute of Workflow, when you initialize a new workflow passing the params, you initialize a new Action association. Then you could just go ahead and do:

@workflow.actions 

to access the Actions. You cannot get the last one unless the Action has some attribute that defines that "last" characteristic (like a date given by the user). So consider saving them and then getting you can the last one by ordering them (created_at and updated_at fields). And before adding the persisted Roles, you'll need to also persist the action.

Tiago Farias
  • 3,397
  • 1
  • 27
  • 30
-1

In the end, I decided to create a @current_action_id in my controller that I would update each time I called @workflow.actions.build. I ended up with this add_role method.

def add_role
  unless @workflow.actions.empty?
    @workflow.save!

    role = Role.find(params[:role_id])
    roles = Action.find(current_action_id).roles
    roles << role unless roles.include? role or current_action_id <= 0
  end
end

Thank you @engineersmnky for the tip on saving my workflow before adding the role.

Rishi
  • 945
  • 2
  • 15
  • 23