I have a rule that creates a new node of another type upon the creation of a new node.

For example, when someone creates a node 'member_primary_information', a 'member_secondary_information' node is created.

What's not working is when I create to auto create a node reference from primary to secondary information.

I use the populate field action on the noderef field, and in the php:

return array(
  0 => array('nid' => $member_secondary_information->nid),
);

This does not work.

On the otherhand, if I do

return array(
  0 => array('nid' => $node->nid),
);

This works fine, of course that's not what I want, that would make the node reference itself, but just as a test.

So referencing to the secondary node with the primary node doesn't work for some reason. Could it be that the secondary node isn't created in time to be referenced?

Thanks in advance.

Comments

mitchell’s picture

Component: Rules Core » Rules Engine

Why don't you use tokens?

Flying Drupalist’s picture

If I try to put a token into the node reference field, it says blah blah is not a valid node. AFAIK, you have to put a node title in there, not a token.

Edit: I temporarily did $node->nid +1, which 'works', but I would still like a less hacky method.

mitchell’s picture

Did you try a token like [referenced-node:nid]?

Flying Drupalist’s picture

Yes, that's what I tried.

nvhzudnip’s picture

I'm having the same issue.
When I create a "Workshop" it should create a "Product" (from Ubercart) automatically.

I created this rule:
ON event After saving new content
IF created content is Workshop
DO
create a new Product with machine readable name "node_added", weight -10
populate a CCK field for Workshop which is a node reference to Product, weight 0
assigning it with this PHP value:
return array( 0 => array('nid' => [node_added:nid]));

Never gets set. When I create the new workshop, it creates a product successfully, but the node reference to the Product is always empty. I've tried:
[node_added:nid]
$node_added->nid
creating a Rules variable set to [node-added:nid] and using that instead

Thank you, Flying Drupalist, I hadn't thought of [node:id]+1, which works, but I would also like to know why what I'm doing doesn't work.

bennos’s picture

think the problem is here, that tokens ca not be used in the php code area.

return array(
0 => array('nid' => $node->nid),
);

That is right. It references the new node(created by the rule) with the node created by the user.
It gives the right Node ID(created by the user) out.

AABoyles’s picture

Version: 6.x-1.2 » 7.x-2.0-rc2

I'm having exactly the same problem: I can set up a rule that should work perfectly, and I get no errors and no results. It seems the bug is that Rules doesn't want to set Node References on newly-created nodes. Besides the [node:id]+1 hack, anyone know any alternate solutions?

that0n3guy’s picture

I got this working in D7 using a rule set and multiple rules (probably don't need to though).

The trick is to "save" the entity before you try adding stuff to it.

rule component (rule set)

Rule1:
* create new entity
* save entity (check to do it immediately)

Rule2:
* modify whatever I want in my new entity

I'm not sure why you are doing this with a php code area since you can easily do it w/out.

jh3’s picture

Here is what seems like the D6 solution to your problem: http://drupal.org/node/820938

I am trying to achieve what I just linked (which also seems like what you're trying to do) but in D7. It's a bit confusing because of the differences between the d6/7 rules UI (not using rules all too much doesn't help either). I also do not know how to get the node/field tokens in a rule in D7. Was this functionality removed?

that0n3guy’s picture

Nope, its in there... you just need to mess around with the data selector thing. Its way better than the old token system. What I posted in #8 is an outline of how I did what you want. You might be able to do it w/ a single rule like:

[events]
After saving new content

[conditions]
Node-is of type:Data Selector= node (created content)
set content type for what you want

[actions]
1. Entity-create new entity: Value Node (fill out all that info) | Set author too: dataselector= node:author
2. Entity-save entity: dataselector = entity-created | Force saving checked (I don't know if this is necessary but its how I got it to work)
3. Data-Set data value: dataselector = entity-created:field-yourreffield
set value: dataselector = node (created):nid

Something like that.... I have done this in D7 with entity_reference module but I would think references module would be the same.

jh3’s picture

I feel like I'm pretty close. I can't figure out how to get the node content that's just been created into the action as a variable (or something else, I just need the nid).

As I said before, I'm trying to replicate what's been done here http://drupal.org/node/820938 but on d7.

Here's what I currently have set up (I am using the default Article and Basic Page content types for testing):

[event]
After saving new content

[conditions]
Content is of type: Basic Page

[actions]
action set: Create an article and refer it

-------------------------------------

[action set: Create an article and refer it]
Variables:

  • Data type = node, Machine name = article_node, Usage = Parameter + Provided
  • Data type = User, Machine name = article_user, Usage = Parameter + Provided

Elements:

  • Fetch entity by id: Entity type = user, Data selector = article-user:id, Variable label = author_id
  • Create a new entity: Entity type = node, Content type = article, Title = Article for [article-node:title], Author = author_id, Variable label = created_article_node*
  • Save entity: Data selector = created-article-node, Force save immediately is checked

* This is the only action that allows me to see the node reference field I added to the Basic Page content type

Now what I have "works": when I create a new Basic Page an Article is automatically created with a title of "Article for [node title of the Basic Page]"

What I cannot seem to figure out is how to get the nid from the article that is automatically created back into the Basic Page's node reference field. This is what the D6 example does, but with the content types story and page instead of article and basic_page.

NikLP’s picture

I worked with this information above to try and help the above guy, but after about an hour I got nowhere with it either... *subscribe*

jh3’s picture

I think I've finally figured it out.

What I wanted: After creating a 'basic page', automatically create an 'article' and then insert a reference to the newly created article node into the node reference field in the basic page node.

Below is an export of the rule. This example is using the default article and basic page content types in d7. If you want to use it you'll probably have to create a node reference field in the basic page content type.

{ "rules_basic_page_article_noderef" : {
    "LABEL" : "When a basic page is created, create an article and reference it",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules" ],
    "ON" : [ "node_insert" ],
    "IF" : [
      { "node_is_of_type" : { "node" : [ "node" ], "type" : { "value" : { "page" : "page" } } } }
    ],
    "DO" : [
      { "entity_create" : {
          "USING" : {
            "type" : "node",
            "param_type" : "article",
            "param_title" : "Article for [node:title]",
            "param_author" : [ "node:author" ]
          },
          "PROVIDE" : { "entity_created" : { "entity_created__article" : "Created article node" } }
        }
      },
      { "entity_save" : { "data" : [ "entity-created--article" ], "immediate" : 1 } },
      { "data_set" : {
          "data" : [ "node:field-article-noderef" ],
          "value" : [ "entity-created--article" ]
        }
      }
    ]
  }
}

To recreate this manually:

  1. Create a new rule and set React on event to After saving new content
  2. Add a new condition
    • Keep the data selector set to node
    • Select Basic page as the content type to check for
  3. Add a new Create a new entity action
    • Select node as the entity that should be created
    • Select Article as the type of node that should be created
    • Enter Article for [node:title] as the title
    • Enter node:author as the Author data selector
    • Modify the fields under provided variables if you wish. I changed them to "Created article node" and "entity_created__article".
  4. Add a new Save entity action
    • Set the data selector to entity-created--article (or whatever you named this variable in the previous action)
    • Check Force saving immediately
  5. Add a new Set a data value action
    • Set the Data data selector to the node reference field. In my case it's called node:field-article-noderef.
    • Set the Value data selector to entity-created--article (or whatever you named the newly created article node)

That should be it. Test the rule by creating a new basic page. It should automatically fill in the Article Reference field with the article node that's automatically created after saving the new basic page node.

GlitchFreak’s picture

I had a similar use case as the OP and this is the way I went about doing it in Rules for D7.

I wanted to create a new Member Account every time I created a new Member Profile (both are custom content types). The Member Account has a node reference field (field_member_account_member) that I wanted to populate with the Member Profile node.

So basically, the following should happen:

1. Create the Member Profile node
2. Save the Member Profile node
3. Create the Member Account node automatically
4. Populate the field_member_account_member field with the Member Profile Node
5. Save the Member Account node

So creating the rule was as follows:

1. Create a new rule
2. Add Event: After Saving New Content
3. Add Condition: Content has type and set the content type (my content type was 'Member Profile')
4. Action: Fetch entity by ID

  • Entity Type: Node
  • Data Selector: node:nid
  • Revision Selector: node:vid
  • Fetched Entity - Variable label: 'Fetched Member Node'
  • Fetched Entity - Variable name: 'fetched_member_node'

5. Action: Create a new entity

  • Entity Type: Node
  • Content Type: Member Account
  • Title: 'Related Members Account' (I suggest using Auto Node Titles instead of this field as it makes updating the titles easier)
  • Author: 'site:current-user'
  • Created Entity - Variable Label 'Created Member Account'
  • Created Entity - Variable Name 'created_member_account'

6. Action: Set a data value

  • Data: 'created-member-account:field-member-account-member' (Note: I want to update the new 'created-member-account' field called 'field-member-account-member')
  • Value:'fetched-member-node' (Note: I wanted to reference the fetched member profile that I had fetched during step 4.)

7. Action: Save entity

  • Entity: 'created-member-account' (Note: This is the new node that I want to save)

I hope this helps anybody who is attempting the same.

stoltoguzzi’s picture

I have a similiar problem but I need:
- to memorize the node-id of the current node (where I start from)
- on this node I have a rules link to add a new node, this is another node-type, let say issue
- if the user stores (onsave) this new node it should be linked to the father-node (the node memorized before)

I can not see how to pass this information, do I need to define a session-variable for this?

Thanks for some help.

GlitchFreak’s picture

if the user stores (onsave) this new node it should be linked to the father-node (the node memorized before)

Must the node always be saved or can the user choose to save it or not to save it?

NikLP’s picture

This might help? http://drupal.org/project/nodereference_url

Basically it passes an extra argument to the node create page which prepopulates a node reference, which I believe is what you're trying to do. Simple, great module.

stoltoguzzi’s picture

@GlitchFreak
the user should be free to save or to cancle.
I tried using the "Execute PHP.." to store the current node as a sesson-variable when the father node is viewed/selected. Then using rules link there would be a function to create a new node, saving this node the session variable fatherNode together with the current node should link this to documents, I would like to use relation to do this.
But it does not realy work.

stoltoguzzi’s picture

@NikLP
Thanks for this, will have a look at this module.
Until now I intendet to use the relation module but...

NikLP’s picture

I would guess you might be able to port the above module to use relation if that was necessary?

mitchell’s picture

Issue tags: +FAQ

tagging

drvdt’s picture

Component: Rules Engine » Rules Core

Dear jh3,
Your comment is correct!!!
Thank you very much,

This will do this task: when create NODE A --> auto create NODE 1 and Reference NODE A to NODE 1

margyly’s picture

Issue summary: View changes

I can create the node and set some fields in it, but I can't set its path. When I try to set entity-created:url Drupal says "The selected data property doesn't support writing."

Am I missing something?

RAWDESK’s picture

I've had a similar issue with referencing to a node that was still in 'creation mode', not via Rules but in plain php code, hook_node_submit to be more precise.

Here's how i solved it with a similar +1 trick :

if(empty($node->nid)) { 
	$nid = db_query('SELECT MAX(nid) FROM {node}')->fetchField() + 1;
} else {
	$nid = $node->nid;
}
$related_node->field_related_products['und'][]['target_id'] = strval($nid);
node_save($related_node);
jiv_e’s picture

Thanks, @RAWDESK!

Your idea is good but if the last node is deleted you will get a wrong node ID. This should be safer:

  if(empty($node->nid)) {
    $nid = db_query("SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_name = 'node' AND table_schema = DATABASE( );")->fetchColumn();
  }
  else {
    $nid = $node->nid;
  }

See: http://stackoverflow.com/a/12500309/406818

TR’s picture

Status: Active » Fixed
Issue tags: -FAQ

The original poster's issue was addressed by #8, then again in more detail by #13 and #14. I don't think there's anything more to say about that.

Posts after that seem to talk about problems that are just 'similar'. Different problems should be discussed in their own issues, where they can detail their exact circumstances. Intermingling problems just confuses this issue and obscures the fact that great solutions were already provided long ago.

TR’s picture

Status: Fixed » Closed (fixed)