Trouble understanding where to register fields - field

I am installing this Nova package: https://novapackages.com/packages/classic-o/nova-media-library and am having trouble figuring out where to put this block of code:
Add field to the resource:
use ClassicO\NovaMediaLibrary\MediaLibrary;
class Post extends Resource
{
...
public function fields(Request $request)
{
return [
...
MediaLibrary::make('Image'),
...
];
}
...
}
I've looked around, but am very new to Laravel, so I'm just a little confused. I understand that it is a field, so I've looked here: https://nova.laravel.com/docs/1.0/resources/fields.html#place-field, but don't really understand the location where these can be registered.
I appreciate any insight or context here. Thank you!

With Laravel Nova, they tried to make everything as easy as possible. So, a Resource is what adds all the functionality to your Model, and a Model represents (in some way) a table in your database. A resource is just a class that extends from Resource, and has some functions to be completely functional.
So, in your example, you should have a Model called Post, the code showing is an incomplete Resource called Post (that's why you se those three points before and after the function). As you read the Resource documentation, you will see that the function fields() always returns an array of Fields. The code
MediaLibrary::make('Image')
is, indeed, a field, that's why it's inside de array. The code that you have is just an example, and it's purpose is to illustrate that the MediaLibrary field can be used as any other field. I strongly recommend that you take enough time to read about Models, Eloquent, Resources and Fields.

Related

Super CSV and multiple bean mapping

I came across a problem mapping multiple beans with Super CSV. I got a csv file, containing information for multiple beans (per line). But as I can see from examples on the website it is only possible to map each line into one bean (not into two or more beans).
Is there a way of doing this? The only way I can think of is creating a new bean, containing the all beans I need and do a deep mapping, i.e.:
class MultiBeanWrapper {
Address addreass;
BankAccount bankAccount;
}
...
String[] FIELD_MAPPING = new String[]
{address.street, bankAccount.bankNumber};
...
beanReader.read(MultiBeanWrapper.class, processors));
I didn't try this, because I want to be sure that there is no other / better way.
Thanks for your help
Daniel
No, you can't read a line into multiple beans - sorry! (I'm not sure what this would even look like - would you get a List<Object> back?)
You have a few options:
Add a relationship between the objects
Then can use a mapping like parent.fieldA, parent.child.fieldB. In your scenario Address and BankAccount aren't related semantically, so I'd recommend creating a common parent (see next option)
Add a common parent object
Then you can use a mapping like parent.child1.fieldA, parent.child2.fieldB. This is what you've suggested, but I'd recommend giving it a better name than Wrapper - it looks like a customer to me!
Oh, and I'd recommend trying stuff out before posting a question - often you'll answer your own question, or be able to give more details which will get you better answers!

Is it right to use extension methods in my case?

I use MVC4 and entity framework 5 in my project and I've lots of tables. As a rule of our project, we don't delete any records from database, each record has a isActive field and if that field is false, then we consider it deleted. I wanted to write an extension method to get active records and after some googling I wrote this:
public static IQueryable<Company> GetAll(this IQueryable<Company> source)
{
return source.Where(p => p.isActive);
}
Now I can use my extension method to get only active records like
Context db = new Context();
db.Company.GetAll();
But let's say I've 50+ tables in my database, is it a good approach to write the same extension method for each of my tables. Is there a better way to write a only one GetAll() extension method for all of our tables? Actually I'm not even sure if is it right way to use extension methods for this instance?
Could somebody please help me and show me the right way? I appreciate if you help with code examples.
It depends on how you are using Entity Framework, if you are depending on the normal generator (and I think you do), your case gets harder and I never had a similar case study. But, if you use normal POCO classes generator, you can use a base class let's call it CEntity which is a base class for each of your other classes (tables).
Are we there yet? No, to continue with this, I prefer to use the Repository Pattern, and you can make that repository generic (CEntity), for example:
public class Repository<CEntity> where CEntity : class
{
public IQueryable<CEntity> GetAll()
{
return source.Where(p => p.isActive);
}
}
And this is how to use it:
Repository<Company> com = new Repository<Company>();
Repository<Employee> emp = new Repository<Employee>();
var coms = com.GetAll(); // will get all ACTIVE companies
var emps = emp.GetAll(); // will get all ACTIVE employees
This is off the top of my head, if you had any other problems, put them as comments, glad to help.
Just as a point of interest, this is exactly how I implement my data layers, and i think its awesome :)
I also jam a repository in the middle as well but the general concept should work with or without.
Here's some working code examples of how I use this method in my blog for some similar use cases.
https://github.com/lukemcgregor/StaticVoid.Blog/blob/master/Blog/Data/Entities/Post/PostRepositoryExtensions.cs
I've found that it makes some pretty elegant code while still not restricting what you can do too much. Like i said, i think this method is awesome and really recommend its usage.

MVC: I need to understand the Model

I've been working with the MVC pattern for a while now, but I honestly don't feel like I truly understand how to work with and apply the "Model" ... I mean, one could easily get away with using only the Controller and View and be just fine.
I understand the concept of the Model, but I just don't feel comfortable applying it within the pattern... I use the MVC pattern within .NET and also Wheels for ColdFusion.
"the Model represents the information (the data) of the application and the business rules used to manipulate the data" - yes, I get that... but I just don't really understand how to apply that. It's easier to route calls to the Controller and have the Controller call the database, organize the data and then make it available to the View. I hope someone understands where my confusion resides...
I appreciate your help in advance!
Look at it like this. When your client requests a page this is what happens (massively trimmed):
He ends up at your controller
The controller gets the necessary data from your model
The controller then passes the data to the view which will create your HTML
The controller sends the HTML back to the client
So client -> controller -> model -> controller -> view -> controller -> client
So what is the model? It is everything that is required to get the data required for you view!
It is services
It is data access
It is queries
It is object mapping
It is critical 'throw exception' style validation
Your controller should not be writing your queries if you are sticking to the pattern. Your controller should be getting the correct data required to render the correct view.
It is acceptable for your controller to do a few other things such as validating posted data or some if/else logic but not querying data - merely calling services (in your model area) to get the data required for your view.
I suppose it's just what you decide to call the different bits in your application. Whichever class you use to pass information from the Controller to the View can be seen as/called "The Model".
Typically we call Model our entity classes, and we call View Model the "helper" classes, for lack of a better word, we use when a "pure" entity (i.e., one that will be stored in the database) doesn't suffice to display all the information we need in a View, but it is all mostly a naming thing.
Your model classes shouldn't have any functions; ideally a model class will have only properties. You should see model classes as data containers, information transporters. Other than that they are (mainly) "dumb" objects:
// This would be a model class representing a User
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
How do you actually pass information (whatever that might mean in your context) form your controller to your View and vice versa? Well then, that's your model. :)
Here is the way I have explained before:
Controller: determines what files get executed, included, etc and passes user input (if any exists) to those files.
View: anything that is used to display output to user.
Model: everything else.
Hope that helps.
Model is the code representation of your base Objects. While some less data-intensive systems may be light on the model end of MVC, I am sure you will always find an applicable use.
Let's take a contrived (but realistic) example to the usefulness of a model:
Say I am making a Blog. My Blog has Post objects. Now, Posts are used in and around the site, and are added by many users in the system. Our system was coded for people to enter HTML into their posts, but low and behold, people are starting to add pasted text. This text uses "\n" as the newline character.
With a model, this is a relatively simple fix. We simply make a getter that overrides postText:
public function get postText() {
return this.postText.replace("\n", "<br />");
}
Suddenly, we can affect behavior across the entire site with a few lines of simple code. Without the implementation of a model, we would need to find and add similar functionality where ever postText is used.
The Model in MVC is all about encapsulation and flexibility of a codebase as it evolves over time. The more you work with it and think about it in this manner, the more you will discover other cases that would have been a nightmare otherwise.
--EDIT (you have added to your question above):
Let us take this same example and use your Controller calling the database. We have 9 Controller classes for vaious pages/systems that use Post objects. It is decided that our Post table needs to now have a delete_fl. We no longer want to load posts with delete_fl = 1.
With our Post model properly implemented, we simply edit the loadPosts() method, instead of hunting down all the cases across the site.
An important realization is that in any major system, the Model is more of a collection of files than a single monolith. Typically you will have a Model file for each of your database tables. User, Post, etc.
model: word, sentence, paragraph
controller: for (word in sentence), blah blah... return paragraph
view: <div>paragraph.text</div>
The idea is to separate the concerns. Why not just have the controller logic in the view as well? The model represents the business objects, the controller manipulates those objects to perform some kind of task and the view presents the result. That way, you can swap an entire view for a different one and you don't have to rewrite the entire application. You can also have people work on different layers (model, controller, view) without affecting the other layers to a significant degree.
By combining the controller and the model, you are making your code less maintainable and extensible. You are basically not performing object-oriented programming as you are not representing the things in your database as objects, you are just taking the data out and sending it to the view.
The model contains business logic (i.e. significant algorithms) and persistence interaction - usually with a database. The controller is the MVC framework: Wheels, Struts, .NET's MVC approach. The view displays data that the controller retrieves from the model.
The big idea going on with MVC is that the view and model should be unaware of the controller - i.e. no coupling. In practice there's at least some coupling that goes on, but when well done should be minimal, such that it allows for changing the controller with low effort.
So what should be happening is a request hits the controller, typically a front controller, where there should be some glue code that you've written that either extends some controller object or follows some naming convention. This glue code has the responsibility for calling methods on the correct service layer object(s), packing that data inside of some sort of helper - typically an Event object - and sending that to the correct view. The view then unpacks data from the Event object and displays accordingly.
And when done well, this leads to a domain model (a.k.a. model) that is unit testable. The reason for this is that you've divorced the algorithms from any framework or view dependencies. Such that you can validate those independently.

Polymorphic inline model forms in django

I have a Person model which has many Animal models as pets. Dog is an Animal with a "favorite bone" field, and Cat is an Animal with a "likes catnip?" field and a "favorite fish" field.
#models
class Person(db.model):
pass
class Animal(db.model):
models.ForeignKey(Person) #owner
name = CharField()
class Dog(Animal):
favorite_bone = CharField()
class Cat(Animal):
favorite_fish = CharField()
likes_catnip = BooleanField()
I would like to inline edit all of a Persons pets, in the Person admin form however, I've read that Django inline admin forms don't support polymorphic inline forms[1], in that, you will only get the parent class fields (e.g. not the favorite_bone or favorite_fish and likes_catnip fields.
Where does this problem come from?
What changes could be made to the framework to accommodate this?
If these changes should not be made, why not?
[1] http://www.mail-archive.com/django-users#googlegroups.com/msg66410.html
(This is an old question, but I thought I'd add an answer in case it is still useful. I've been working on a similar question recently.)
I believe it would be challenging to change Django form-generation to do what you want. The reason is that the inline formset uses a single class/form for all rows of the inline -- there are no configuration options that are evaluated per-row of the inline form. I have convinced myself of this by reading the code itself --- look for "inline" and "formset" in django.contrib.admin.options.py, especially lines 1039-1047 (version 1.5.1). This is also the reason why you can't have some fields read-only in existing items and changeable in new items (see this SO question, for example).
The workarounds found for the readonly case have involved a custom widget that produces the desired behavior such as this one. That still won't directly support polymorphism, however. I think you would need to end up mapping your divergent types back to a common ancestor (e.g. have all pet classes able to return a dict of their unique attributes and values), and then create a single custom widget that renders out the polymorphic part for you. You'd then have to map the values back on save.
This might be more challenging than it is worth, and may lead back to the suggestion in the other answer to not use admin for this :-)
may have a look here.
but i think the modeladmin is currently not able todo such things.
you are able to create a custom edit view for your model...
there is almost everything possible.
It may be possible to do this with Generic Relations.

Symfony Admin Generator in multi user setup (restricting records in LIST view)

I am using SF 1.2.9 to build a website. I want to use the admin generator to provide admin functionality for the object models I have used (specifically LIST, edit and delete).
I have read the Symfony docs (Chapter 14), but unless, I am very much mistaken, all examples I have come accross so far, seems to be written for a single user environment only. Meaning that the list of records returned to the user is essentially, ALL the records in that table. In a multiuser environment, this is irresposible at best, and potentially, a security threat. It is a necessary requirement to restrict the list of records returned to a user to only those that they own (i.e. created).
Suppose I have a table with (YML) schema like this:
foobar_dongle:
id: ~
title: varchar(255)
info: longvarchar
owner_id: ~
created_at: ~
where owner id is a FK into a user table.
Assume I generate an admin module like this:
symfony propel:generate-admin backend FoobarDongle --module=dongle
Question:
How do I modify the list of records returned to a user in the LIST part of the code generated by the admin generator? As I mentioned above, currently, (i.e. out of the box), the admin generator presents the user (rather naively, I feel), with the ENTIRE set of records for the model being administered. I need to be able to restrict that list somehow, so that I can only return records owned by that user.
This is what I am trying to find out how to do.
I would be most grateful to anyone who can show me how I can restrict the list of records returned when using the admin generator for administration of an object model. Ideally, I would like to be able to specify a custom method that has all the custom 'filtering' logic - but so long as I can restrict the LIST of records a user can see (in admin), to only the records that he is the owner of, that is all I want to be able to do.
If you only want to restrict the returned objects in one or two modules, do this:
Go to the actions.class.php file of your module. There should be no methods by default and the class should inherit from autoModuleNameActions you. Insert the following method:
protected function buildQuery()
{
$query = parent::buildQuery();
// do what ever you like with the query like
$query->andWhere('user_id = ?', $this->getUser()->getId());
return $query;
}
But this becomes unhandy if you do it for more modules. In this case I would advice to create a new admin generator theme.
And if you want to make the query depending on some custom parameter in the admin generator config file, then you have to extend this file. But is not just done with adding a new parameter. You can read this article how to do this.
If you want to know more about the auto generated classes, have a look at this class: cache/[app]/[env]/modules/auto[ModuleName]/actions/actions.class.php.
Edit after comments:
I think you looked at the wrong class. Look here: cache/[app]/[env]/modules/auto[ModuleName]/actions/actions.class.php.
I set up a Propel project to check it and the method that is interesting for you is:
protected function buildCriteria()
{
if (is_null($this->filters))
{
$this->filters = $this->configuration->getFilterForm($this->getFilters());
}
$criteria = $this->filters->buildCriteria($this->getFilters());
$this->addSortCriteria($criteria);
$event = $this->dispatcher->filter(new sfEvent($this, 'admin.build_criteria'), $criteria);
$criteria = $event->getReturnValue();
return $criteria;
}
I also posted the whole content of this class to pastebin. It is a lot, the function is in line 245. Even if you don't find this class, you should be able to override this method like this:
protected function buildCriteria()
{
$criteria = parent::buildCriteria();
// do something with it
return $criteria;
}
I don't know about these criteria objects, so I can't help you with that but I hope the other things help you.
You should use sfGuardPlugin to provide your login/user functionality - it includes user groups and permissions that can be assigned to users and/or groups.
Using security.yml you can then configure which permissions/credentials are required to access individual actions. IE: you can allow everyone to access the list/update/delete actions, but only people with the create permission to access the create page.
The docs for sfGuardPlugin are worth reading:
http://www.symfony-project.org/plugins/sfGuardPlugin
Plus this section from the jobeet tutorial covers sfGuard and also use of security.yml and credentials:
http://www.symfony-project.org/jobeet/1_2/Propel/en/13
And to round off, this page from the book is relevant too:
http://www.symfony-project.org/reference/1_2/en/08-Security (although not sure it covers anything that isn't in the page i linked from jobeet)

Resources