Hello everyone and thanks for reading , i have little problem , i installed the yii user extension.
I created another table that has a relationship with the user table.
Yii created the relationships with the "user" table automatically but when i try to use the relationship it gives me the below message;
include(Users.php): failed to open stream: No such file or directory
Could this be because User Model is not with the other models but instead in Modules/User.....
How can i make it work ?
eg
array(
'header' => __('Title'),
'name' => 'id_employer_contract',
'value' => '$data->user->username',//user is the name of relationship
),
When trying to access the User.php model from outside of the User module, the file has not been imported yet.
If you look at the init() method of the UserModule.php file, you'll see that the User.php file gets imported via the user.models.* statement.
There are a few different way to import this file from other parts of your system:
Add application.modules.user.models.* to the import section of your main.php. This will make it available everywhere in your application
Call Yii::import('application.modules.user.models.*'); right before the area of code depending on User.php
Call Yii::app()->getModule('user'); right before the area of code depending on User.php. This will call the init() method in the User module.
Look at "include(Users.php): failed"
You can change the relation mapping (auto generated by Gii) from this:
'user' => array(self::BELONGS_TO, 'Users', 'user_id')
To this:
'user' => array(self::BELONGS_TO, 'User', 'user_id')
That should do the trick.
In another version of Yii the according model might be YumUser instead of User when creating your relation, did the job for me:
'user' => array(self::BELONGS_TO, 'YumUser', 'user_id')
The problem that you have is that the Table name for users is called "users" so when yii is resolving this for model generation it would resolve the user model to be "Users" however the yii-user module extension has the model as "UserModel" in a file named User.php
This means that in essesnce the file named Users.php does not exist.
To resolve this just change the relationship in your new model to'user' => array(self::BELONGS_TO, 'User', 'User'), and not 'user' => array(self::BELONGS_TO, 'Users', 'User'),
Related
I've started Yii a month ago and am finding it very intuitive, yet somehow confusing regarding widgets.
In the app i'm developing, although I sometimes use Active Record, I cannot use it's relations as I am using MyIsam (and this cannot be changed) and it has no support for foreign keys.
My issue is I have a CGridView and want to add custom data to it, but am having issues.
It is a 1-to-many relationship with the FK in the right model, but as I said, I cannot use AR's magic.
I have this, an Applications Model and a Profile model. The Profile model has an application FK.
I got a function so when I'm rendering the CGrid I can fetch the name of each Application instead of its *id_app*.
public function appName($id){
$app= Yii::app()->db->createCommand()
->select('name')
->from('tbl_aplications a')
->where('a.id=:id_app', array(':id_app'=>$id))
->queryRow();
return $app;
}
In the auto-generated templates, in the Profile Admin.php view, I got:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'profile-application-grid',
'dataProvider'=>$model->search(), //maybe the issue is with this criteria? It is currently 'as-is' after the template generation
'filter'=>$model,
'columns'=>array(
'id',
'name',
array(
'name'=>'id_app',
'header'=>'Aplication',
And here is my issue, I've tried (and all sorts of variations):
'value' => 'ProfileApplication::model()->appName($data->id_app)',
'value' => 'ProfileApplication::model()->appName(id_app)',
'value' => 'ProfileApplication::model()->appName("id_app")',
and all I get is null as a result because it is passing the actual string instead of each row's value. If I pass a direct ID to the function's query, it returns correct value, like ->where('a.id=:id_app', array(':id_app'=>3))
Is it the search criteria that needs to be altered?
I've found similar questions but all of them use AR such as Profile->application or something along those lines and I as I said, I cannot use it due to MyIsam restrictions.
Any tips are appreciated to this newcomer, or links to a solution regarding a similar issue .
To use the value attribute such as that you need, as PrplHaz4 said, a data provider. Then, the $data variable is what has the magic, and it must be used in a string because it is eval()'ed behind the scenes. Here is an example of what you are trying to do:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'item-grid',
'dataProvider'=>$model->search(),
'columns'=>array(
array(
'name' => 'id',
'header' => 'Item ID',
),
array(
'name' => 'category_search',
'header' => 'Category',
'value' => '$data->category->name',
),
),
)); ?>
That grabs the name attribute of the related item category model. In the relations() function of the item model:
return array(
'category'=>array(self::BELONGS_TO, 'ItemCategory', 'category_id'),
);
And in the relations() function of the item category model:
return array(
'items'=>array(self::HAS_MANY, 'Item', 'category_id'),
);
You should still be able to use ActiveRecord relations with MyISAM, I beleive the only difference is that with MyISAM, if you use a model generator (gii or cmd line), it will not automatically create the relations. Instead, you will have to specify the relation yourself in the Profile model. This is effectively creating a "soft" fk for use with AR.
public function relations()
{
return array(
'applications'=>array(self::HAS_MANY, 'Applications', 'id_app'),
);
}
That will not entirely solve your problem though, because you will need to use a dataprovider that brings the application models along with the profile models. Something like this:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'profile-application-grid',
'dataProvider'=>Profile::model()->with('Applications'),
'filter'=>$model,
'columns'=>array(
'id',
'name',
array(
'name'=>'applications.name',
'header'=>'Application',
),
I have a controller named users and index action in it. By default I have the path
get '/users' => 'users#index', :as => 'users'
Now I want to create one more path with a different parameter being passed
get '/users/:city' => 'users#index', :as => 'list_users'
But this gives as error, No route matches {:controller=>"users"}.
I ran rake routes and found the path I defined to be present over there but it doesn't works.
What shall be done to make this work.
I'm using Inherited resources for my controllers. And now i have model:
class Sms < ActiveRecord::Base
end
And i want controller for it, where i make defaults:
class Admin::SmsesController < Admin::InheritedResources
defaults :resource_class => Sms,
:collection_name => 'smses',
:instance_name => 'sms'
end
but i can not understand, why it still trying to get "Smse" model:
NameError in Admin::SmsesController#index
uninitialized constant Smse
Pls help.
The problem is that Rails doesn't know that the plural of Sms is Smses. If you go to the Rails console you should see that:
> "Sms".pluralize
=> "Sms"
> "Smses".singularize
=> "Smse"
When faced with a plural it doesn't recognise, singularize just truncates the final "s", which is why your app is looking for a nonexistent Smse model.
You will save yourself a lot of headaches by configuring Rails to pluralize/singularize your models correctly. In the file config\initializers\inflections.rb you should find some examples of how to do this. What you want is:
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'sms', 'smses'
end
Then I don't think you should need to put the defaults option in there at all - it should all work out of the box.
Does anyone know how to do separate login forms and authenticate on two different tables?
I can't go with one table and different roles... client requested to do separate tables...
I've got user login system based on Yii framework login system. But now I have to do separate for admin user (administration module).
The way I solved this issue was to create two identical copies of this plugin from the Yii Framework library:
http://www.yiiframework.com/extension/yii-user/
Then I refactored it and called it "Customer" and changed the config so that it used a different table etc.
In the configuration options for Yii, I also included these options to keep the sessions separate (config/main.php):
'components' => array(
...
'user' => array(
// enable cookie-based authentication
'allowAutoLogin' => true,
'loginUrl' => array('/user/login'),
'class' => 'RWebUser', // added - possibly uses the Rights user manager
),
'customer' => array(
// enable cookie-based authentication
'allowAutoLogin' => true,
'loginUrl' => array('/customer/login'),
'stateKeyPrefix' => 'customer',
),
'customerUser' => array(
'class' => 'CWebUser',
'stateKeyPrefix' => 'customer',
'loginUrl' => array('/customer/login'),
),
You could add a property to your UserIdentity component called, for example, role. Then change the authenticate() method of UserIdentity so that it fetches from the account table corresponding to role. Now you need to make sure that UserIdentity->role is set before invoking UserIdentity->authenticate(). If you are following the yiic webapp template then this would be in SiteController. Two very easy ways (among others):
Have two different login pages, one for normal users and one for admins and each has its own URL. Implement it with two views and two login action methods in SiteController, each sets up UserIdentity->role appropriately before invoking UserIdentity->authenticate(). This approach duplicates code and you'll be able to see how to sort that out once it's working.
Use one login page with a form element (checkbox perhaps) that an admin user selects. This form's action method UserIdentity->role according to form state.
I have a Rails 3.0 web app that allow user to create own path to the application.
example : www.my_app.com/user_company_name
So I store a custom path in user DB field. User can changing path throught a input.
I have added this validation in model
validates_presence_of :custom_page
validates_format_of :custom_page, :with => /^([a-z]|[0-9]|\-|_)+$/, :message => "Only letter (small caps), number, underscore and - are authorized"
validates_length_of :custom_page, :minimum => 3
validates_uniqueness_of :custom_page, :case_sensitive => false
But I don't know how I can validate url to check it isn't in conflict with another route in my routing.
For example in my route.rb I have
resources :user
Validation need to don't allow using www.my_app.com/user, how I can do that?
Thanks, vincent
In your routes, you match the company name to a variable
match 'some_path/:company_name.format'
you can then do the lookup using company_name which rails will populate for you.
Validating the uniqueness of the custom_page variable should be enough to ensure there's no overlap. (note that validate uniqueness of doesn't scale -- if this will be big, you need a db constraint as well) as long as users can only specify one field.
If you're letting users specify
'some_path/:custom_path_1/:custom_path_2.format'
then you have to validate across both fields, and now it's getting messy. Hope you're not doing that.
You can try a custom validation to weed out "user"
validate :custom_page_cant_be_user
def custom_page_cant_be_user
errors.add(:custom_page, "can't be `user`") if self.custom_page =~ /^user$/i
end
assuming :custom_page comes in as a basic [a-z], if :custom_page has /user you need to update the regex a bit.