How to add PushType media programmatically for seeding


(Danny) #1

How would I go about setting :asset fields programmatically?

PushType uses the jsonb datatype to store node fields. Which can be seeded (sed…?) as shown here Using jsonb with Ruby on Rails.

Article.create!({
			              title: 'Example',
			              slug: 'example',
			              field_store: {
					              name: 'example',
					              # etc
				      }
}

I got that far, but adding images requires uploading the file, PushType handling it to create associated records and getting a record_id which in turn can be saved using the method above. How would I go about that?

Suppose the question goes as far as asking for documentation for how to create PushType class records programmatically. not just media records. I created some other nodes and they’re all drafts.


(Aaron Russell) #2

You shouldn’t have to worry about the internal field_store - you should be able to mass assign all your custom fields as if they were normal attributes.

Article.create!({
  title: 'Example',  # standard attribute
  slug: 'example',   # standard attribute
  name: 'example'    # custom field attribute
})

In terms of Assets and attachments, the node record just saves the ID so you’d need to create the asset record first.

asset = PushType::Asset.create!(file: path_to_file)

Article.create!({
  # ... attributes
  thumbnail_id: asset.id
})

Some field types are a little more complex and require a deeper data structure. Eg:

Article.create!({
  thumbnail_id: asset.id,
  author: {                 # struct field is an object/hash
    name: 'Joe Bloggs',
    age: '30'
  },
  meta: [                   # matrix field is an array of objects
    {
      key: 'Topic',
      value: 'Foo'
    },
    {
      key: 'Audience',
      value: 'Bar'
    }
  ]
})

You get the gist. More broadly, internally PushType is actually very simple. The are only three models that you need to worry about.:

  • PushType::Asset - all file uploads are an Asset, regardless of file type
  • PushType::Node - which all you node classes inherit from. Normally you’d create records through your own classes.
  • PushType::User

That’s it.

There is also a full rest API… but that is not documented at all! That’s one for another day :slight_smile:


(Danny) #3

Asset creation worked perfectly, thanks for that! Seeding assets has always been a problem for me previously. Good to have found out how it is done.

I want to seed a user account as I reset the database quite frequently and using `rake push_type:create_user becomes tiring after a while :stuck_out_tongue:

User.create!({name: 'Daniel', email: 'daniel@example.com', password: '12345678', password_confirmation: '12345678'})

The code above causes a NameError, despite creating the record.

NameError: undefined local variable or method `unconfirmed_email' for #<PushType::User:0x0055b930e7f1f0>

I’m not entirely sure why it would complain as I checked the PushType::User class and there is a email field defined (based on the validation):

PushType::User Excerpt

module PushType
  class User < ActiveRecord::Base

  include PushType::Customizable

  validates :name, presence: true
  validates :email, presence: true, uniqueness: true
  # etc
end 

The user account is not valid somehow because signing in causes a ActiveRecord::RecordNotFound at the sign_in_path (http://localhost:3000/sign_in)

EDIT:
I used the seed_dump gem to dump the database contents of a User generated using the script.

PushType::User.create!([
	                       {name: "Daniel", email: "daniel@gmail.com", field_store: {}, encrypted_password: "$2a$11$NVfQ/znBBSsSG2rJJVlC/OUWQE6m8kDD0opnzskdKgHzGu5bGVjtu", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: "Generated account", confirmed_at: "2017-01-28 09:32:10", confirmation_sent_at: "2017-01-28 09:32:10"}
                   ])

The code above works, funny because I did try passing in an encrypted_password.


(Aaron Russell) #4

Not sure exactly what’s going on here. Take a look at how the rake task does it:

I don’t think you need to give the password_confirmation and the confirmation timestamps and dummy token value are probably needed. Not sure if that’s relevant.

Are you working on an otherwise clean Rails app, or are you adding PushType on to an existing app? Do you have your own devise configuration?


(Danny) #5

The reason it didn’t work for me is because I didn’t give those last three parameters.
It’s a clean app.